Copyright: Copyright © 1988-1997 Sybase, Inc., Release 5.5.02


Copyright

Sybase® SQL Anywhere™

SQL Anywhere Release: 5.5.02

Last modified:

Copyright © 1991-1997 Sybase, Inc. and its subsidiaries. All rights reserved. Printed in the United States of America.

Information in this manual may change without notice and does not represent a commitment on the part of Sybase, Inc. and its subsidiaries.

The software described in this manual is provided by Sybase, Inc under a Sybase License agreement. The software may be used only in accordance with the terms of the agreement.

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. and its subsidiaries.

Sybase, Inc. or its subsidiaries claim copyright in this program and documentation as an unpublished work, revisions of which were first licensed on the date indicated in the foregoing notice. Claim of copyright does not imply waiver of other rights of Sybase, Inc. and its subsidiaries.

ComponentPack, InfoMaker, PowerBuilder, Powersoft, S-Designor, SQL Smart, and Sybase are registered trademarks of Sybase, Inc. and its subsidiaries. AppModeler, the Column Design, DataArchitect, DataExpress, Data Pipeline, DataWindow, MetaWorks, NetImpact, ObjectCycle, Optima++, PowerBuilder Foundation Class Library, PowerBuilder Translation Toolkit, PowerScript, PowerTips, Powersoft Portfolio, Powersoft Professional, ProcessAnalyst, StarDesignor, Sybase SQL Anywhere, Watcom, Watcom SQL Server, Web.PB, and web.sql are trademarks of Sybase, Inc. and its subsidiaries. Certified PowerBuilder Developer and CPD are service marks of Sybase, Inc. or its subsidiaries. DataWindow is a patented proprietary technology of Sybase, Inc. or its subsidiaries.

AccuFonts is a trademark of AccuWare Business Solutions Ltd.

All other trademarks are property of their respective owners.

 User's Guide


User's Guide

Copyright

 About This Manual

 PART 1. Introduction to SQL Anywhere

 PART 2. Tutorials

 PART 3. Using SQL Anywhere

 PART 4. Transact-SQL Compatibility

 PART 5. The SQL Anywhere Programming Interfaces

 PART 6. SQL Anywhere Reference

 Glossary


About This Manual
User's Guide

About This Manual

Subject

This manual describes how to use the Sybase SQL Anywhere database management system, and provides tutorial, task-based, and reference material to assist you in learning all aspects of the product..

Audience

This manual is for anyone using SQL Anywhere, whether as a developer or as an administrator.

Where to find information

SQL Anywhere is a multi-platform DBMS with many different uses. The table lists some of the starting points for using the SQL Anywhere User's Guide.

If you want to...	Go to these parts of the manual
Get an overview of the SQL Anywhere database management system	Part One: Introduction to SQL Anywhere
Learn how to create and manage databases in a Windows 95 or Windows NT environment.	"Managing Databases with Sybase Central"
Learn about the SQL language for querying data.	Part Two: Tutorials
Learn how to create and manage databases in an OS/2 or command-line environment.	The chapter "Working with Database Objects"
Learn how to connect to a SQL Anywhere database from a client application.	The chapter "Connecting to a Database"


Introduction to SQL Anywhere
User's Guide

PART 1. Introduction to SQL Anywhere

This part provides an overview of the Sybase SQL Anywhere database management system, previously called Watcom SQL.  The part includes a description of the new features in this release.

 CHAPTER 1. Introduction

 CHAPTER 2. New Features in SQL Anywhere 5

 CHAPTER 3. Overview of SQL Anywhere


Introduction
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 1. Introduction

About this chapter

This chapter introduces the SQL Anywhere and the SQL Anywhere User's Guide.

 About SQL Anywhere

 Upgrading databases to SQL Anywhere

 About this manual


About SQL Anywhere
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 1. Introduction

About SQL Anywhere

A full SQL database management system

Developed on personal computers for personal computers, SQL Anywhere is a full-featured transaction-processing SQL database management system which has excellent performance while requiring fewer resources (memory space, disk space, and CPU speed) than other database management systems.

SQL Anywhere is available for Windows NT, Windows 95, Windows 3.x, OS/2, NetWare, Solaris/Sparc, HP-UX, AIX, DOS, and QNX operating systems.

SQL Anywhere can be used as a standalone database management system or (on non-UNIX operating systems) as a network database server in a client/server environment.

Database files are compatible between versions and across all operating systems. The operating systems on which you are entitled to run SQL Anywhere depends on your license agreement.

SQL Anywhere is a fast and efficient database for many environments, from notebook computers to servers supporting large numbers of concurrent users. It is a flexible and scalable solution for today's diverse needs.

ODBC support

With an efficient ODBC driver and full ODBC 2.1 level 2 support, as well as other interfaces, SQL Anywhere is also an ideal database for developers. Whether you are using C, PowerBuilder, or other application development tools, and whether you are developing single-user or client/server applications, SQL Anywhere provides you with all the capabilities you expect from a full SQL database server.

 Supplied components

 A DBMS for many platforms and environments


Supplied components
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 1. Introduction

About SQL Anywhere

Supplied components

Sybase SQL Anywhere is a multi-platform database management system that is available in both Standard and Professional Editions, and which is included as a part of several other products, including Powersoft PowerBuilder, Optima++, and S-Designor. Depending on which operating system you are using, and which particular product you have purchased, you may have access to some or all of the features described in this manual.

The components available to you depend on the operating system you are running, and on the particular product you have purchased. This section describes the contents of the SQL Anywhere Standard Edition. Additional tools and components are included in SQL Anywhere Professional. If you received SQL Anywhere as part of another product, consult the product documentation to see which components are available to you.

SQL Anywhere components

The SQL Anywhere Standard Edition CD-ROM includes the following components. Your use of these components is subject to the software license agreement.

♦	Standalone database engine   For same-machine database access.

♦	Network server and client   For client/server database access across a network.

♦	SQL Remote   Message-based replication technology.

♦	Sybase Central   Graphical administration utility

♦	ISQL   Interactive SQL utility.

♦	Command-line administration utilities   For database management tasks.


A DBMS for many platforms and environments
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 1. Introduction

About SQL Anywhere

A DBMS for many platforms and environments

SQL Anywhere is available for the following operating systems:

♦	Windows and Windows NT   The standalone database engine and multiuser network server are available for each of Windows 3.x, Windows 95, and Windows NT. The Sybase Central administration utility is available for Windows 95 and Windows NT only.

♦	OS/2   The standalone database engine and multiuser network server are available for OS/2. These include a Presentation Manager version of ISQL, and command-line administration utilities. Sybase Central is not available for OS/2.

♦	NetWare   The network server is available as a NetWare Loadable Module (NLM). The ISQL utility is also available as an NLM.

♦	UNIX   The standalone engine is available for Sun Microsystems Solaris/Sparc, Hewlett Packard HPUX, and IBM AIX. This includes a character-mode ISQL and command-line administration utilities.

♦	QNX   The network server only is available for QNX. This includes a character-mode ISQL and command-line administration utilities.

♦	DOS   The standalone database engine and multiuser network server are available for DOS. This includes a character-mode ISQL and command-line administration utilities.

 For information about supported releases of these operating systems, see your Read Me First.


Upgrading databases to SQL Anywhere
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 1. Introduction

Upgrading databases to SQL Anywhere

Which databases need to be updated?

You do not need to upgrade your SQL Anywhere 5.0 databases to use SQL Anywhere 5.5.

If you have databases created with Watcom SQL, you need to upgrade your database to SQL Anywhere 5.0 or 5.5 if you wish to use some of the features introduced in SQL Anywhere. The following summary describes the version you must have in order to use some features.

♦	To use procedures and triggers, you must be using a database that is at least release 4.0.

♦	To use SQL Remote on existing databases, you must upgrade your database to release 5.0.

♦	To access the Transact-SQL system procedures and system views, you must upgrade your database to release 5.0.

How to upgrade a database

The Upgrade utility is provided to upgrade Watcom SQL 4.0 databases to SQL Anywhere format. The Upgrade utility is accessible either from Sybase Central or as the DBUPGRAD command-line utility. The following statement at the command line upgrades a 4.0 database file named TEST.DB to a SQL Anywhere format:

dbupgrad -c "dbf=test.db;uid=dba;pwd=sql"

If you wish to use replication on an upgraded database, you must also archive your transaction log and start a new one on the upgraded database.


About this manual
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 1. Introduction

About this manual

This manual describes how to build, run, and maintain databases using SQL Anywhere, and how to build database applications that work with the SQL Anywhere standalone database engine and network database server.

The manual includes the following sections.

♦	Tutorials

♦	Using SQL Anywhere

♦	Transact-SQL Compatibility

♦	The SQL Anywhere Programming Interfaces

♦	Reference

 Platforms and products covered

 Documentation overview

 Document conventions

 Product installation

 Contact information


Platforms and products covered
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 1. Introduction

About this manual

Platforms and products covered

This documentation applies to all supported platforms of SQL Anywhere. Not all features are available on all platforms. The operating systems and features you are entitled to use depends on the product you have purchased and your license agreement.

If you have obtained SQL Anywhere as part of another product, such as Powersoft PowerBuilder, S-Designor, or Optima++, you may not have access to all features described in this manual.


Documentation overview
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 1. Introduction

About this manual

Documentation overview

Tutorials

The Tutorials part provides a step by step introduction to the following:

♦	Managing databases with Sybase Central

♦	Using the Interactive SQL (ISQL) utility

♦	Structured Query Language (SQL).

The chapter "Using ISQL" shows you how to use ISQL, and the rest of the tutorial introduces most of the important features of SQL, using a sequence of examples based on the supplied sample database.

Using SQL Anywhere

Each chapter in the part "Using SQL Anywhere" describes a different aspect of the product. Taken together, they provide a guide to building, running, and maintaining databases and database applications with SQL Anywhere.

Transact-SQL  Compatibility

Transact-SQL  Compatibility is for users wishing to develop applications and databases compatible with Sybase SQL Server and the Transact-SQL dialect of SQL it supports. The part describes the SQL Anywhere support for Transact-SQL.

The SQL Anywhere Programming Interfaces

The SQL Anywhere Programming Interfaces explains how to use the programming interfaces to SQL Anywhere. The bulk of the section describes the Embedded SQL and ODBC interfaces for use by C programmers. Developers using ODBC-enabled application development systems, such as Powersoft PowerBuilder, do not need to use this section: the information in Using SQL Anywhere and Reference, together with your application development system's documentation, cover all the information needed to develop SQL Anywhere applications from ODBC-enabled applications.

Reference

Reference is a complete reference guide to SQL Anywhere programs, supported commands with complete syntax, error messages, and system tables.

Available formats

The contents of this manual are provided in print and as online Help, accessible through Sybase Central, ISQL, and as a desktop icon. The online Help version of the manual is more up to date than the printed documentation.


Document conventions
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 1. Introduction

About this manual

Document conventions

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

 Typographic conventions

 Graphic icons


Typographic conventions
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 1. Introduction

About this manual

Document conventions

Typographic conventions

The documentation uses the following typographic conventions:

Item	Description
Code	SQL and program code is displayed in a monospaced font
User entry	Text entered by the user is displayed in a bold sans serif typeface
new term	New terms introduced in the text are displayed in a bold serif typeface
emphasis	Emphasized words are displayed in italic
SQL keywords	SQL keywords are displayed in upper case
  For a description of syntax-formatting conventions, see "Syntax conventions".


Graphic icons
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 1. Introduction

About this manual

Document conventions

Graphic icons

The following icons are used in this documentation:

Icon	Meaning
	A database server, such as Sybase SQL Server or Sybase SQL Anywhere.
	A SQL Anywhere database engine, or a SQL Anywhere network server and Client. All applications that work with a SQL Anywhere standalone engine work identically with a SQL Anywhere network server, via a SQL Anywhere Client.
	A Sybase Replication Server.
	A Replication Agent. A replication agent is required for a database to act as a primary data site in Sybase Replication Server installations.
	A SQL Anywhere Log Transfer Manager.
	A client application.


Product installation
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 1. Introduction

About this manual

Product installation

Installation instructions for SQL Anywhere are in the SQL Anywhere Read Me First.


Contact information
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 1. Introduction

About this manual

Contact information

Contact information for technical support and sales inquiries is provided on the separate Contact Sheet in this package.


New Features in SQL Anywhere 5
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 2. New Features in SQL Anywhere 5

About this chapter

This chapter describes features new to SQL Anywhere 5.

 What's in a name?

 New features overview

 New features in the Watcom-SQL language

 New sample database


What's in a name?
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 2. New Features in SQL Anywhere 5

What's in a name?

Previous releases of this product were named Watcom SQL.

With the Sybase/Powersoft merger of February 1995, Watcom became a part of Sybase, Inc. Watcom SQL is now a part of the Sybase System 11 Server product line, and the new name of the product, SQL Anywhere, reflects that change. The principal dialect of SQL supported by SQL Anywhere is named Watcom-SQL.

The Sybase SQL Anywhere name reflects the versatility of the product, and the emphasis on both scalability and mass deployment. Sybase SQL Anywhere gives you the high performance and reliability of a transaction-processing SQL server, the ability to scale from single users to many users, and the flexibility to deploy on multiple platforms. It's a database designed for the workplace.

The new features outlined in this chapter include data replication and Transact-SQL-compatibility, along with many others. We think you will agree that these new features, built on the proven foundations of Watcom SQL, make SQL Anywhere a powerful workplace complement to Sybase SQL Server in the System 11 Server product line.


New features overview
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 2. New Features in SQL Anywhere 5

New features overview

While there have been many improvements and enhancements, the following are major areas around which the new release has been designed.

Feature	Description	For more information
SQL Remote data replication	SQL Remote is a message-based replication system for replication between SQL Anywhere databases. It is built to be easy to use, centrally administered, and ideal for replication to laptop and other occasionally-connected users' personal databases.	See chapters "Introduction to SQL Remote Replication"  and "SQL Remote Administration."
Sybase Central database management tool	Sybase Central is a graphical database administration tool that runs on the Windows 95 and Windows NT 3.51 operating systems. Sybase Central conforms closely to the Windows 95 interface guidelines, making it easy to learn and use.	See the chapter "Managing Databases with Sybase Central"
Transact-SQL compatibility	SQL Anywhere 5.0 includes a set of extensions to the Watcom-SQL language from the Sybase Transact-SQL dialect. This makes the development of compatible applications for SQL Anywhere and SQL Server database servers much more straightforward, and also brings new features to all SQL Anywhere users.	See the chapters "Using Transact-SQL with SQL Anywhere" and "Transact-SQL Procedure Language".
ODBC 2.5 support	SQL Anywhere 5.0 now supports ODBC 2.5 at level 2 for the Windows 95 and Windows NT operating systems, and ODBC 2.1 for the Windows 3.x operating system.
Open Server Gateway	The Open Server Gateway. allows client applications to work with both SQL Server and SQL Anywhere database servers	See the chapter "Using the Open Server Gateway".
Data replication with Sybase Replication Server	The Open Server Gateway allows SQL Anywhere to act as a replicate site database in Sybase Replication Server installations. A separate product, the SQL Anywhere Replication Agent, allows SQL Anywhere databases to act as primary data sites in Replication Server installations
Performance improvements	Performance enhancements do not require extensive documentation. However, there are major improvements to the speed of many tasks performed by SQL Anywhere since the last major release
System functions and performance monitoring	An extensive set of system functions allows access to statistics concerning database engine or server performance. These are also available from Sybase Central. Statistics from the Windows NT engine and network server can be viewed in the NT Performance Monitor.	See the chapter "Monitoring and Improving Performance".
SQL extensions	The Watcom-SQL language has been extended in many areas to provide more flexibility and power to SQL Anywhere users	See "New features in the Watcom-SQL language".
Transaction log mirroring	SQL Anywhere can optionally maintain two identical transaction logs. Transaction log mirroring provides additional protection against loss of data due to disk failure	For more information on transaction log mirroring, see the chapter "Backup and Data Recovery".
MAPI system procedures	System external procedures are supplied that allow MAPI e-mail calls to be made from stored procedures	See the chapter "Using Procedures, Triggers, and Batches".
Calls to external DLLs from procedures	You can now create procedures that call external DLLs	See the chapter "Using Procedures, Triggers, and Batches".


New features in the Watcom-SQL language
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 2. New Features in SQL Anywhere 5

New features in the Watcom-SQL language

Watcom-SQL is the dialect of SQL supported by the SQL Anywhere standalone database engine and network server. The extensions to Watcom-SQL in this release include improvements in several areas.

Feature	Description	For more information
Stored procedure extensions	Stored procedures are easier to create, have more flexible parameter declarations (including default values and optional parameters in CALL statements), and can return status information.	See the chapter "Using Procedures, Triggers, and Batches".
User-defined functions	With the new CREATE FUNCTION statement you can use the SQL Anywhere stored procedure language to define new functions, you can use just like other functions.	See the chapter "Using Procedures, Triggers, and Batches".
Batches	This release introduces support for batches of SQL statements. Control statements (IF, LOOP, and so on) are now available in command files as well as in procedures and triggers.	See the chapter "Using Procedures, Triggers, and Batches".
Statement level triggers	Triggers can be made to fire once after each statement, as an alternative to the row-level triggers supported in previous releases	See the chapter "Using Procedures, Triggers, and Batches".
New Watcom-SQL language elements	These include global variables, new operators, and new comment specifiers	See "Watcom-SQL language elements".
New built-in functions	New numeric, string, date and time, and data type conversion functions have been added, as well as new system functions. New functions include: ♦ PATINDEX for pattern matching ♦ System functions describing database properties	See the section "Watcom-SQL Functions".
User-defined data types	You can define your own data types from the existing base data types supported by SQL Anywhere	See the section "SQL Anywhere Data Types".
Extensions to data manipulation statements	The DELETE, and UPDATE statements have been extended to support criteria based on joins.	See "DELETE statement" and "UPDATE statement".
System stored procedures	SQL Server provides stored procedures for carrying out database management functions. The system tables of SQL Server and SQL Anywhere are different, but several of the system stored procedures are provided to carry out analogous actions on each.
More flexible column constraints	Before this release, all constraints associated with a table, whether column constraints or table constraints, were held as a single table constraint. Column constraints are now held individually, allowing them to be individually deleted or replaced	See "ALTER TABLE statement"
Other new statements	Other new statements have been added: LOAD TABLE, UNLOAD TABLE, TRUNCATE TABLE, MESSAGE, EXECUTE IMMEDIATE, RETURN, and others	See the listing in section "Watcom-SQL language elements".


New sample database
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 2. New Features in SQL Anywhere 5

New sample database

The sample database has been changed in this release. The new sample database contains employee, sales, product and financial information for a small company. The database is a subset of the PowerBuilder demo database. The following diagram illustrates the sample database structure.

The sample database is called SADEMO.DB.


Overview of SQL Anywhere
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 3. Overview of SQL Anywhere

About this chapter

This chapter presents an overview of SQL Anywhere architecture on a single computer and on a network.

An application developed in a standalone environment can be deployed in a multiuser network environment with no alteration to the code whatsoever.

This chapter also introduces terminology for relational database management systems, and describe the database management tools included in your SQL Anywhere package.

 The SQL Anywhere engine and the SQL Anywhere server

 Running SQL Anywhere on a single computer

 Running SQL Anywhere on a network

 Running mixed operating systems on a single computer

 SQL Anywhere programming interfaces

 The SQL Anywhere programs


The SQL Anywhere engine and the SQL Anywhere server
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 3. Overview of SQL Anywhere

The SQL Anywhere engine and the SQL Anywhere server

SQL Anywhere includes two executables for managing databases:

♦	The network server, for managing databases using a client/server arrangement on networks

♦	The database engine, for managing databases on a single computer in a standalone mode

PowerBuilder and InfoMaker users—This chapter contains some information about connecting to a SQL Anywhere network server. The SQL Anywhere network server is not included with PowerBuilder and InfoMaker.

The SQL Anywhere server and SQL Anywhere engine manage databases in exactly the same way and are completely compatible. However, the SQL Anywhere engine has no support for network communications.

Server and engine—The terms engine and server are used in this manual to refer to the database engine and database server. In contexts where either the engine or the server could be used, the terms are used interchangeably. When the engine and server need to be distinguished, the terms standalone engine and network server are sometimes used to emphasize which is meant.

The following sections describes the architecture for running SQL Anywhere on a single computer using the SQL Anywhere engine and for running SQL Anywhere across a network using the SQL Anywhere network server.

  For information on running more than one operating system on a single computer, see the section "Running mixed operating systems on a single computer".


Running SQL Anywhere on a single computer
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 3. Overview of SQL Anywhere

Running SQL Anywhere on a single computer

The figure shows the architecture of a standalone SQL Anywhere installation, running a single database engine and working with a single database. All more complicated arrangements are elaborations of this basic setup, so you should understand how the basic setup works, even if you are operating a multiuser client/server installation.

Standalone SQL Anywhere components

The components of the basic standalone SQL Anywhere setup are:

♦	The client application

♦	The SQL Anywhere interface layer

♦	The SQL Anywhere database engine

♦	The database

Database users do not directly manipulate database files. Instead, their client application communicates with the database engine, using a programming interface supported by SQL Anywhere, and the database engine handles all manipulation of the actual database.

 For information on a client application and a database server for different operating systems running on the same computer, see the section "Running mixed operating systems on a single computer".

 The client application

 The SQL Anywhere database engine

 The database


The client application
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 3. Overview of SQL Anywhere

Running SQL Anywhere on a single computer

The client application

A client application communicating with the SQL Anywhere database engine must do so using a programming interface supported by SQL Anywhere. The client application calls functions from one of the SQL Anywhere programming interfaces.

The client application together with the programming interface layer form the client side of the setup.

ODBC-enabled application development systems

If you are building a client application from an ODBC-enabled application development system, such as Powersoft PowerBuilder, or others, you do not need the information in the section "Programming Interfaces". These application development systems already implement an ODBC interface internally. Application development systems form an extra layer that sits between the application developer and the SQL Anywhere interface, and you should consult your application development system's documentation to understand how to communicate with a database engine.

PowerBuilder and InfoMaker use the ODBC interface.

If you are using one of the programming interfaces directly to develop client applications, you should understand the SQL Anywhere programming interface you are using. The programming interfaces are described fully in the section "Programming Interfaces".


The SQL Anywhere database engine
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 3. Overview of SQL Anywhere

Running SQL Anywhere on a single computer

The SQL Anywhere database engine

The database engine and the database together form the server side of the setup. A client application manipulates a database by sending requests to the database engine.

SQL Statements

Communications between a client application and a database engine take the form of Structured Query Language (SQL) statements. For example, a SELECT statement, or query, is used to extract information from a database. An UPDATE statement may be used to modify the contents of one of the database tables.

The client application sends the SQL statements and the database engine processes them and sends the results back to the client application.

Running an application against a SQL Anywhere network server

Running an application against a SQL Anywhere network server generally requires an extra component to handle network communications from the client computer (see "Running SQL Anywhere on a network"). However, for applications on the same computer the database server can be run in exactly the same manner as the standalone database engine described here using a direct connection to the network server.

If a SQL Anywhere Client is running and the network server is running on the same machine, the Client will not be used by client applications connecting on the same machine; the connection will be direct.

  For a discussion of running a client application and a database server for different operating systems on a single computer, see "Running mixed operating systems on a single computer".


The database
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 3. Overview of SQL Anywhere

Running SQL Anywhere on a single computer

The database

SQL Anywhere is a relational database system. The database itself is stored on one or more disk drives, and consists of the following objects:

Database objects	Description
Tables	Hold the information in the database
Keys	Relate the information in one table to that in another
Indexes	Allow quick access to information in the database
Views	Are computed tables
Stored procedures	Hold queries and commands that may be executed by any client application (stored procedures are not available in the SQL Anywhere Desktop Runtime system)
Triggers	Assist in maintaining the integrity of the information in the database (triggers are not available in the SQL Anywhere Desktop Runtime system)
System tables	Hold the information about the structure of the database
Multiple databases on a single database engine

A single SQL Anywhere database engine can manage access to several databases simultaneously. You can start and stop databases from database administration tools or client applications, and you may connect to any of the currently running databases on a database engine.

As far as the database user is concerned, interaction with a database engine is always through a connection. Each time users connect to a database, supplying valid user ID and password, they are connected to a specific database on a specific database engine. Once a connection is established, it provides a channel through which all communications go. The connection insulates the user from the other components of a running database system such as network sessions and interprocess communication mechanisms.

Multifile databases

SQL Anywhere supports multifile databases. When a SQL Anywhere database is first initialized, it is composed of one file—the root file. As tables and other database objects are added to the database, however, they may be stored in different files, which may be on different disk drives from the root file.

Users of the database (other than the database administrator) need not be aware of the physical location of database files. The database engine handles all access to the files and shields this complexity from the user.


Running SQL Anywhere on a network
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 3. Overview of SQL Anywhere

Running SQL Anywhere on a network

SQL Anywhere Server products support connections from many users at a time, over a network. In this case, the database engine runs on one computer (the database server computer), while client applications run on other computers (client computers).

The SQL Anywhere server supports multiuser network access to SQL Anywhere. The SQL Anywhere standalone engine does not support multiuser access or network communications.

PowerBuilder and InfoMaker users—This chapter contains some information about connecting to a SQL Anywhere network server. The SQL Anywhere network server is not included with PowerBuilder and InfoMaker.

The client side of the SQL Anywhere setup sends SQL queries and commands over the network to the server side, which carries out commands and sends the results of queries back to the client.

The SQL Anywhere Client

The SQL Anywhere Client is a program that handles network communications to the SQL Anywhere database server. The SQL Anywhere Client is a program named DBCLIENT (the Windows 3.x version is called DBCLIENW). The SQL Anywhere Client communicates with the SQL Anywhere network server. The standalone engine cannot handle communications from the SQL Anywhere Client.

For QNX, the database client is different from other operating systems. Instead of being a separate executable, the SQL Anywhere Client is a library named dbclient, which is loaded dynamically by client applications.

Standalone setup versus network setup

From the client application's point of view, there is no difference between the standalone setup and the network setup. In the single-user setup, a client application sends requests and commands to the database engine. In the multiuser setup, these requests are sent to the SQL Anywhere Client instead. In each case, the client application has a single point of contact with the DBMS. The additional complexity of handling requests in a multiuser, networked environment is hidden from the client application.

Standalone applications work with the SQL Anywhere network server—Once a client application is developed and working on a standalone SQL Anywhere setup on a single computer, no changes are needed to the application in order for it to work as a client application in a network environment against a SQL Anywhere server.

  For more information on the SQL Anywhere network server, see the SQL Anywhere Network Guide.

 SQL Anywhere multiplatform support

 Some database terms


SQL Anywhere multiplatform support
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 3. Overview of SQL Anywhere

Running SQL Anywhere on a network

SQL Anywhere multiplatform support

The SQL Anywhere standalone database engine is available for the Windows 3.x, Windows 95 and Windows NT, OS/2, and DOS operating systems. The SQL Anywhere database server is available for Novell NetWare, Windows 95 and Windows NT, OS/2, Windows 3.x, DOS, and QNX operating systems.

One SQL Anywhere database server can support multiple clients operating on different operating systems, communicating via different network protocols.


Some database terms
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 3. Overview of SQL Anywhere

Running SQL Anywhere on a network

Some database terms

With a single database running on a single database engine, the default settings make the engine name, the database name, and the database file the same, apart from the path and extension associated with the file. In this situation there is little ambiguity when talking about the database.

In environments with multiple databases, multiple database files, and several database engines operating simultaneously, it is important to distinguish among the different components that make up a running SQL Anywhere DBMS.

Terms used in this documentation

Term	Description
Database file	Even though the tables of a database may be held in several files on several disk drives, each database is identified by a single root file. Throughout this book, when reference is made to a database file, it is referring to the root file
Database name or alias	A SQL Anywhere database engine or server can run several databases simultaneously, managing access to each of them. When a database is started on a database engine, it is assigned a database name, also called the database alias. If no database name is explicitly assigned, the database receives the name of the root file with the path and extension removed
Server or engine name	When a database server or engine is started, it is assigned a server name or engine name. The server or engine name is entirely distinct from the name of the database engine program itself. By default, the server name is the first database name. For example, if a database engine is started with database C:\PB\EX\PSDEMODB.DB and no name is explicitly given, then the name of the engine is PSDEMODB
Clients and servers	Both the client side and the server side of a SQL Anywhere client/server setup consist of several components. The terms client and server themselves are commonly used to describe not only the computers on which each side of the setup sits, but also the programs that are communicating, and also the collection of software components on each of the computers. Throughout this guide, the terms client and server are qualified whenever possible to specify which of these meanings is used


Running mixed operating systems on a single computer
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 3. Overview of SQL Anywhere

Running mixed operating systems on a single computer

SQL Anywhere supports situations in which client applications and the database engine run under different operating systems on the same computer. This support requires a SQL Anywhere Client (DBCLIENT) for the client application operating system. You can think of the mixed operating system setup as a client/server network arrangement, with both client and server sides residing on the same computer.

The situations where this can occur are:

♦	DOS or Windows client applications with an OS/2 engine

♦	DOS or Windows 3.x client applications with a Windows 95 or Windows NT engine

Mixed operating systems can occur when running DOS or Windows 3.x client applications with a Windows 95 or Windows NT engine

 DOS or Windows client applications on OS/2

 DOS or Windows 3.x clients on Windows 95 or NT


DOS or Windows client applications on OS/2
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 3. Overview of SQL Anywhere

Running mixed operating systems on a single computer

DOS or Windows client applications on OS/2

The OS/2 standalone engine or network server can be accessed from a DOS or WIN-OS/2 client application on the same machine.

The client application communicates with the SQL Anywhere Client for the client application operating system. (The DOS and Windows 3.x SQL Anywhere Clients are installed with SQL Anywhere for OS/2 or as a separate install with the DESKTOP RUNTIME SYSTEM FOR OS/2.) The SQL Anywhere Client handles the communication with the OS/2 database engine or server using named pipes or DDE.

Command lines for  DOS or Windows 3.x clients

The command line to run the DOS client is:

dbclient  engine-name

The command line to run the Windows 3.x client is:

dbclienw  engine-name

Other servers

SQL Anywhere also supports access to network servers elsewhere on the network simultaneously via a separate communication link in the SQL Anywhere Client.

  For more complete information, see the SQL Anywhere Network Guide.


DOS or Windows 3.x clients on Windows 95 or NT
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 3. Overview of SQL Anywhere

Running mixed operating systems on a single computer

DOS or Windows 3.x clients on Windows 95 or NT

The Windows 95 or Windows NT database engine or server can be accessed from a DOS or Windows 3.x client application on the same machine.

The client application communicates with the SQL Anywhere Client for the client application operating system. (The DOS and Windows SQL Anywhere Clients are installed with SQL Anywhere.) The SQL Anywhere Client handles the communication with the Windows 95 or Windows NT database engine or server, using named pipes (Windows NT) or DDE (Windows 95).

Command lines for DOS or Windows 3.x SQL Anywhere clients

The command line to run the DOS SQL Anywhere Client is:

dbclient engine-name

The command line to run the Windows 3.x SQL Anywhere Client is:

dbclienw engine-name

Other servers

SQL Anywhere also supports access to network servers elsewhere on the network simultaneously via a separate communication link in the SQL Anywhere Client.

  For more information, see the SQL Anywhere Network Guide.


SQL Anywhere programming interfaces
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 3. Overview of SQL Anywhere

SQL Anywhere programming interfaces

The conversation between a client application and a database engine or server takes place through a SQL Anywhere programming interface. The available programming interfaces are:

♦	High level interfaces in ODBC-enabled application development systems such as Powersoft PowerBuilder and in applications with ODBC-enabled macro languages

♦	Low-level full-function interfaces: ODBC and embedded SQL

♦	High-level interfaces: WSQL DDE and WSQL HLI

This section describes the main characteristics of the high and low-level interfaces.

  For more detailed information and guidelines to help you choose the most appropriate interface, see "Programming Interfaces".

 Low-level programming interfaces

 High-level programming interfaces


Low-level programming interfaces
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 3. Overview of SQL Anywhere

SQL Anywhere programming interfaces

Low-level programming interfaces

ODBC and embedded SQL provide low-level interfaces to SQL Anywhere.

ODBC is supported by a wide range of DBMS and is implemented for Windows, Windows NT, and OS/2 as a database driver: a dynamic link library (DLL) that an application invokes to gain access to SQL Anywhere databases. On other platforms, the ODBC interface is implemented as a static library.

Embedded SQL is slightly quicker than ODBC and has a wider set of functions. Embedded SQL is implemented as a C/C++ language preprocessor, which translates SQL statements embedded in your code into calls to the interface. The interface is implemented as a DLL for Windows, Windows NT, and OS/2, and as a library on the other platforms.

The ODBC interface

The ODBC interface is the most widely-used interface to SQL Anywhere.

SQL Anywhere supports the Microsoft Open Database Connectivity (ODBC) interface not only in the Windows and Windows NT environments, but also on DOS, OS/2, the Macintosh, and QNX. This low-level interface provides almost all the functionality of embedded SQL with, (in the SQL Anywhere implementation), only a small performance penalty. Client applications using the ODBC interface can work with many different RDBMS.

SQL Anywhere supports all of the ODBC Version 2.1 API functions (Core, Level 1, and Level 2).

  For a full description of ODBC programming, see the chapter "ODBC Programming".

The embedded SQL interface

The native programming interface of SQL Anywhere is embedded SQL. SQL Anywhere comes with dynamic link libraries (normal libraries in DOS, QNX, and NetWare) and a preprocessor to enable development of C and C++ applications using embedded SQL.

  For a full description of embedded SQL programming, see the chapter "The Embedded SQL Interface".


High-level programming interfaces
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 3. Overview of SQL Anywhere

SQL Anywhere programming interfaces

High-level programming interfaces

SQL Anywhere also provides two higher-level programming interfaces, DDE (Windows and Windows NT only), and HLI (Windows, OS/2, and Windows NT only). High-level interfaces to SQL Anywhere are also provided by ODBC-enabled application development systems and applications.

The DDE interface

The DDE server is a Windows application that enables you to access and alter data in SQL Anywhere databases using dynamic data exchange (DDE). Many Windows applications, including leading spreadsheets and word processors, support the DDE protocol.

The HLI interface

The HLI is provided as a DLL for Windows, OS/2 and Windows NT and can be used from any application or environment that can call DLLs. It is simpler to use than ODBC, but also slower and supports less functionality.


The SQL Anywhere programs
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 3. Overview of SQL Anywhere

The SQL Anywhere programs

SQL Anywhere includes a set of database administration tools, as well as the SQL Anywhere database engine itself.

Each of the database tools is a SQL Anywhere client application and communicates with the database engine using the embedded SQL interface.

The Windows 3.x version of many of the programs has a slightly different name (ending with a W) so that Windows 3.x applications can coexist in the system path with Windows 95, DOS, OS/2, or Windows NT applications.

  For reference information about each of the utilities in your SQL Anywhere package see the chapter "SQL Anywhere Components".

 The SQL Anywhere database engine and server

 The SQL Anywhere Desktop Runtime database engine

 The Sybase Central database management program

 SQL Anywhere administration utilities


The SQL Anywhere database engine and server
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 3. Overview of SQL Anywhere

The SQL Anywhere programs

The SQL Anywhere database engine and server

At the core of SQL Anywhere is the database engine or database server, which handles all requests from client applications and carries out all manipulations of the database.

The name of the database engine or server executable depends on the operating system, as follows:

Operating system	Database Engine or Server Executable
SQL Anywhere, for Windows 3.x	DBENG50W.EXE is a 32-bit database engine, and DBENG50S.EXE is a 16-bit database engine provided for computers that can run Windows 3.x only in standard mode
SQL Anywhere, for operating systems other than Windows 3.x	DBENG50.EXE
SQL Anywhere Desktop Runtime System for Windows 3.x	RTDSK50W.EXE is a 32-bit database engine, and RTDSK50S.EXE is a 16-bit database engine provided for computers that can run Windows 3.x only in standard mode. The runtime database engines are distributable royalty-free on purchase of the SQL Anywhere Desktop Runtime System
SQL Anywhere Desktop Runtime System, for operating systems other than Windows 3.x	RTDSK50.EXE. The runtime database engine is distributable royalty-free on purchase of the SQL Anywhere Desktop Runtime System
SQL Anywhere database server for Windows 3.x	DBSRV50W.EXE is a 32-bit database engine
SQL Anywhere database server, for operating systems other than Windows 3.x	DBSRV50.EXE, DBSRV50.NLM for the NetWare Loadable Module and DBSERVER for QNX
The SQL Anywhere Client, DBCLIENT.EXE, enables client applications to communicate with the network database server. For Windows 3.x, the SQL Anywhere Client executable is named DBCLIENW.EXE.

For QNX, the SQL Anywhere Client is a library named DBCLIENT, which is loaded at run time.


The SQL Anywhere Desktop Runtime database engine
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 3. Overview of SQL Anywhere

The SQL Anywhere programs

The SQL Anywhere Desktop Runtime database engine

The SQL Anywhere Desktop Runtime System contains a runtime SQL Anywhere database engine that supports database manipulation language (DML) SQL commands.

What is it?

The runtime version of the database engine:

♦	Is a transaction-processing database engine

♦	Fully supports the DML subset of SQL commands, such as SELECT, INSERT, UPDATE, and DELETE

♦	Provides full referential integrity, including cascading updates and deletes

♦	Supports declared temporary tables

♦	Allows users to be added to a database

♦	Works with existing databases

Runtime and standalone database engine differences

The functions supported by the SQL Anywhere standalone database engine that are not fully supported in the runtime database engine are as follows:

Standalone database engine function	How it operates in the runtime database engine
Replication	You cannot replicate data
ALTER statements	You cannot use: ♦ ALTER DBSPACE to modify the characteristics of the main database file or extra dbspace ♦ ALTER TABLE to change table definitions ♦ ALTER PROCEDURE to change procedure definitions
CREATE statements	You can use CREATE VARIABLE to create SQL variables. SQL variables do not form part of the database definition You cannot use the following CREATE statements: ♦ CREATE DATATYPE to create user-defined data types ♦ CREATE DBSPACE to create new database files ♦ CREATE INDEX to create indexes ♦ CREATE PROCEDURE to create procedures ♦ CREATE FUNCTION to create user-defined functions ♦ CREATE TABLE to create tables or temporary tables ♦ CREATE TRIGGER to create triggers ♦ CREATE VIEW to create views
COMMENT statement	You cannot add comments to the system table
DROP statement	You cannot use the DROP statement to drop a DATATYPE, DBSPACE, FUNCTION, INDEX, TABLE, VIEW, PROCEDURE, or TRIGGER from the system tables
CALL statement	You cannot invoke procedures
GRANT statement	You can grant the special user permissions (CONNECT, DBA, RESOURCE, GROUP, MEMBERSHIP IN GROUP) using GRANT, but you cannot change permissions on tables and views
REVOKE statement	You can revoke the special user permissions using REVOKE, but you cannot change permissions on tables and views
Triggers	Triggers will not be fired by the runtime database engine
No transaction log	To simplify database administration, the runtime database engine does not employ a transaction log, Users of the runtime database engine should backup their databases by making backup copies of their database file itself
The database engine options that refer to transaction logs (-a,-f)	Not applicable to the runtime database engine
The DBBACKUP options described in the User's Guide that refer to transaction logs ( -r, -t, -x)	Not applicable to the runtime database engine


The Sybase Central database management program
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 3. Overview of SQL Anywhere

The SQL Anywhere programs

The Sybase Central database management program

Sybase Central is a graphical database management tool for Windows 95 or for Windows NT 3.51 or later. Sybase Central is the recommended tool for carrying out the tasks described in the following sections, including the following:

♦	Creating and maintaining databases

♦	Backing up databases

♦	Managing transaction log files

♦	Working with compressed databases

♦	Working with read-only databases

♦	Compacting databases by unloading and reloading


SQL Anywhere administration utilities
User's Guide

PART 1. Introduction to SQL Anywhere

CHAPTER 3. Overview of SQL Anywhere

The SQL Anywhere programs

SQL Anywhere administration utilities

  For a complete description of each of the utilities that come with your SQL Anywhere package, see the chapter "SQL Anywhere Components".

You can access the administrative utilities from Sybase Central, which is the recommended tool for managing SQL Anywhere databases, from ISQL, or as command-line utilities.

Action	Utility	Description
Stopping a database server	stop utility	Stops a running database server or SQL Anywhere Client
Creating and maintaining databases	initialization utility	Creates a new database. If you wish to use a customized sorting and comparison order (collation) for a new database, you need to use the collation utility.
Modifying	erase utility	Erases a database file, log file, or write file
Inspecting database files	information utility	Provides information about a database file or write file
Modifying the transaction log	transaction log utility	Displays or changes the name of the transaction log. Transaction logs are a record of all changes made to a database, and are an important part of database backups. Transaction logs can be translated into ASCII SQL command file form by the log translation utility as part of recovery from some forms of database failure, and applied to a copy of the database made at the time the transaction log was started to restore the database
Backing up databases	backup utility	Performs full or incremental online backup of databases
Validating the database	validation utility	Checks the validity of all indexes on a database table, and should be used in conjunction with backups to maintain the integrity of information in a database
Working with compressed databases	database compression utility	Compresses a database file (compressed database files are usually 40 to 60 percent of their original size)
	uncompression utility	Expands a compressed file Compressed databases are useful in situations where file space is limited. The SQL Anywhere database engine is not able to update compressed database files directly, however, and so compressed databases need to be used in conjunction with a write file created with the write file utility.
Working with read-only databases	write file utility	Manages write files and provides a method of working with read-only databases. There are some situations where it is necessary to work with databases that SQL Anywhere cannot modify directly: read-only databases. Database provided on CD-ROM are a common class of read-only database. Compressed databases are read-only databases. If you wish to test new applications without modifying a production database, a write file is a useful alternative. All changes made to a read-only database are made instead to a write file, leaving the master database unchanged. The SQL Anywhere standalone engine and network server also produce a transaction log, which maintains records of all changes made to the write file. If, at a later point, you wish to apply the changes in the write file to the master database, you can do this by applying the transaction log to the original database using the log translation utility.
Unloading and reloading data	unload utility	Unloads the database. This program creates a text command file named RELOAD.SQL. This command file may be run from ISQL to rebuild the database from scratch. The size of a database file does not decrease when rows are deleted (although future insertions will use the space freed by the deleted rows). You can rebuild a database in order to reclaim the disk space associated with deleted rows. The REBUILD batch or command file (not available in the Windows 3.x version of SQL Anywhere) automates the process of rebuilding a database.
Upgrading databases	upgrade utility	Upgrades databases made using earlier versions of SQL Anywhere to SQL Anywhere version 5.0 format.   For information about upgrading databases, see "The Upgrade utility".


Tutorials
User's Guide

PART 2. Tutorials

This part introduces you to the basics of the SQL language used to query and modify databases. If you are already familiar with SQL, you will not need to read this part.

 CHAPTER 4. Managing Databases with Sybase Central

 CHAPTER 5. Using ISQL

 CHAPTER 6. Using Character-Mode ISQL

 CHAPTER 7. Selecting Data from Database Tables

 CHAPTER 8. Joining Tables

 CHAPTER 9. Obtaining Aggregate Data

 CHAPTER 10. Updating the Database

 CHAPTER 11. Introduction to Views

 CHAPTER 12. Introduction to Subqueries

 CHAPTER 13. Command Files

 CHAPTER 14. System Tables


Managing Databases with Sybase Central
User's Guide

PART 2. Tutorials

CHAPTER 4. Managing Databases with Sybase Central

About this chapter

This chapter introduces the Sybase Central database management tool and is a brief introduction to how Sybase Central can be used for managing database properties.

Detailed instructions on using Sybase Central are available in the Sybase Central online Help. The online Help is arranged as a set of how to windows leading you step by step through database management tasks. In addition, context sensitive Help is available to explain the different interface elements.

Before you begin

Sybase Central requires Windows 95, or Windows NT 3.51 or later.

 Sybase Central and database management

 Navigating the main Sybase Central window

 Adding a table to a database

 Viewing and editing procedures

 Managing users and groups

 Backing up a database using Sybase Central

 Using the Sybase Central online help


Sybase Central and database management
User's Guide

PART 2. Tutorials

CHAPTER 4. Managing Databases with Sybase Central

Sybase Central and database management

Sybase Central is a database management tool that exposes SQL Anywhere database settings, properties, and utilities in a graphical user interface.

Database administration tasks typically fall into two categories:

♦	Tasks carried out by sending SQL statements to the database engine.

♦	Tasks carried out by SQL Anywhere utilities.

Sybase Central provides an easy-to-use interface for both kinds of tasks.

Using Windows 95 or NT

For users with access to Windows 95 or NT, Sybase Central will make your database administration tasks easier and more efficient.

Other systems

For SQL Anywhere users not running Windows 95 or Windows NT 3.5.1 or later, all the tasks you can carry out with Sybase Central can be carried out using ISQL to send SQL statements to the database engine or server, and using the command-line versions of the SQL Anywhere utilities.

For more information about SQL Anywhere utilities, see the chapter "SQL Anywhere Components".


Navigating the main Sybase Central window
User's Guide

PART 2. Tutorials

CHAPTER 4. Managing Databases with Sybase Central

Navigating the main Sybase Central window

This tutorial introduces the Sybase Central user interface. It also describes how to start Sybase Central, how to connect to a database, and how to view a database schema in Sybase Central.

After completing the tutorial you should feel comfortable exploring Sybase Central's capabilities by yourself.

 Start Sybase Central

 Connecting to a database from Sybase Central

 Viewing a database schema


Start Sybase Central
User's Guide

PART 2. Tutorials

CHAPTER 4. Managing Databases with Sybase Central

Navigating the main Sybase Central window

Start Sybase Central

♦	To start Sybase Central in Windows 95 or Windows NT 4.0, select Start [image] Programs [image] SQL Anywhere [image] Sybase Central.

♦	To start Sybase Central from Windows NT prior to Version 4.0, double-click Sybase Central in the SQL Anywhere Program Manager group.

The main Sybase Central window appears.

The Sybase Central window is modeled after the Explorer in Windows 95 and Windows NT 4.0. The main window is split into two vertically-aligned panels. The left panel 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. Sybase Central is at the root of the tree. Plug-ins for Sybase Central, such as the Sybase SQL Anywhere database management system, occupy the first level after the root level.

The right panel displays the contents of the container that has been selected in the left panel. The contents of a container can be viewed in the right panel in several ways: as large icons, small icons, as a list, and alongside their associated details. You can switch between these views by clicking the buttons on the Tool Bar immediately below the Window menu.


Connecting to a database from Sybase Central
User's Guide

PART 2. Tutorials

CHAPTER 4. Managing Databases with Sybase Central

Navigating the main Sybase Central window

Connecting to a database from Sybase Central

This section describes how to connect to the sample database using the user ID DBA and the password SQL.

Logging on— The sample database contains the user ID "DBA", a user with full administration and resource creation rights. The password for this user is "SQL".
By default, all newly-created SQL Anywhere databases contain this user ID and password. It is the responsibility of the database administrator to provide the desired level of security by changing passwords and creating other user IDs.

 To connect to the sample database:

1	Start the sample database (SADEMO.DB) by selecting the Standalone Sample Database menu item from the Sybase SQL Anywhere 5.0 menu. Select Start [image] Programs [image] SQL Anywhere 5.0 [image] Standalone Sample Database.

The SQL Anywhere engine and sample database must be running for any of the following steps to work properly.

2	From the same Sybase SQL Anywhere 5.0 menu, start Sybase Central by clicking the Sybase Central menu item.

3	On the Sybase Central toolbar, click the Connect toolbar button or select Connect from the Tools menu on the menu bar.

4	Enter the user ID DBA and the password SQL, and click OK.

You can save connection parameters as connection profiles to avoid retyping often-used connection parameters. For information about connection profiles, search the Sybase Central online help index for "Connection Profiles".


Viewing a database schema
User's Guide

PART 2. Tutorials

CHAPTER 4. Managing Databases with Sybase Central

Navigating the main Sybase Central window

Viewing a database schema

A database schema is the collection of all objects in the 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

There are a variety of methods for viewing the objects in a database, including the following.

♦	Click a container in the left panel to select that container. The right panel then shows the contents of the selected container. Among the contents of the server container are all the databases you've attached to, including ones you have not yet connected to by entering a user ID and password.

♦	Click once on the plus or minus sign next to containers in the left panel to expand or collapse the hierarchical tree of objects. This allows you to view database objects at levels below the level of the currently selected container. If no plus or minus sign appears next to a container it contains no objects extending beyond the level of that container.

♦	Press the plus or minus keys on the numeric keypad when the selected container has a plus or minus sign beside it. This expands or contracts the container.

♦	Using the right mouse button, click on an object in the right panel and a pop-up menu is displayed. Choose the Open menu item. If the object is a container object—one that can contain other objects such as folders—this causes the object to be selected in the left panel, and displays the contents of that container in the right panel.

♦	Double-clicking a container in either panel causes the container to the selected container in the left panel and displays the contents of the newly-selected container in the right panel.

♦	Double-clicking on the container in the left panel expands or contracts the object's hierarchy in addition to selecting it and displaying its contents in the right panel.

The left panel displays container objects only. The right panel displays the contents of the container object selected in the left panel.

Viewing the tables in a database

The following illustrates the steps taken to examine the contents of a table folder in a database container.

 To examine the tables in a database:

1	Select the Tables folder. You may have to expand the server and database objects in the hierarchical tree in the left panel in order to view the Tables folder.

2	Each table in the Tables folder is itself a container. Select a table in the left panel to reveal the contents of that table in the right panel. Each table object contains folders for columns, foreign keys, relations, indexes, and triggers.

3	Expand the table object in the left panel to reveal its contents in the hierarchical tree. Select each object in the table container by clicking on it once in the left panel. The right panel will display the contents of the table object selected in the left panel.

Viewing database object properties

The properties of database objects such as a database or stored procedures, can be viewed using any of the following methods. In all cases, a tabbed dialog box called a property sheet will be displayed, revealing all editable and non-editable properties.

♦	Using the right mouse button, click on a database schema. From the pop-up menu choose Properties.

♦	While holding the Alt key, double-click database schema in the right panel.

♦	With a database schema selected in the right panel, press the Alt and Enter keys simultaneously.

♦	With a database object selected in either the left or right panel, choose Properties from the File menu.

You can navigate a database by clicking or double-clicking in either panel. Explore the contents of the other folders in the database. Every SQL Anywhere database contains individual folders for the following:

♦	Tables   Base tables stored in the database.

♦	Views   Computed tables, stored in the database as a query and evaluated when accessed.

♦	Procedures & Functions   for using a module-based language consisting of SQL procedures.

♦	User & Groups   for administering who is permitted to use the database.

♦	User-defined Data Types   for creating non-standard data types.

♦	SQL Remote   for administering replication of data in the database.

♦	DB Spaces   for creating more than one .DB file for the database.

You should explore the sample database until you are comfortable locating database objects in the Sybase Central main window.


Adding a table to a database
User's Guide

PART 2. Tutorials

CHAPTER 4. Managing Databases with Sybase Central

Adding a table to a database

This tutorial takes you through the steps adding a table to the sample database. This task includes adding columns to an existing table. The tutorial covers the following interface skills:

♦	Using the table editor to add tables and columns

♦	Using property sheets to add new object properties

♦	Using drag-and-drop techniques to add new objects

To add a table to your database you define the name and properties of your table its columns using a tool called the table editor. The table editor displays the table columns and their properties in a spreadsheet-like grid. When these definitions are saved, the table is created.

 Create a table and adding columns in Sybase Central

 Editing existing tables using the table editor

 Dragging a column to a new table using Sybase Central

 Deleting tables using Sybase Central


Create a table and adding columns in Sybase Central
User's Guide

PART 2. Tutorials

CHAPTER 4. Managing Databases with Sybase Central

Adding a table to a database

Create a table and adding columns in Sybase Central

Tables are added or edited using the table editor, which displays column properties in a grid: column properties are displayed along the top of the grid while the columns are identified by rows, one for every column in the table.

In this tutorial we create a table in the sample database. The new table will describe different offices for the sample database.

 To create a table and columns:

1	Select the Tables folder in the left panel. This can be done by first expanding the server and database containers, then clicking on the Tables folder.

2	Double-click the Add Tables object in the right panel, causing the Table Editor to appear.

3	Type the new table name in the Name text box in the upper left corner of the table editor. In this case, use the name office.

4	Click in the Column Name column of the first row to enter the name of the first column in the table. Use the name office_id.

5	Under the Data Type column choose smallint from the drop down list of standard data types.

6	Do not make any entries under the Size/Precision, Scale and Comments columns. Ensure the entry under the Allow Nulls column is left unchecked so this column can later be used as a primary key.

7	Click the Advanced Table Properties button on the toolbar and enter the comment "Company offices" in the Comment text box. Comments are an optional property.

8	Finish creating the table by clicking the Save and Close toolbar button. The table editor disappears and the office table is added as another table in the Tables folder. It can be viewed in the right panel by selecting the Tables folder in the left panel.

The following section describes how to edit an existing column and add a primary key to the table using the table editor.


Editing existing tables using the table editor
User's Guide

PART 2. Tutorials

CHAPTER 4. Managing Databases with Sybase Central

Adding a table to a database

Editing existing tables using the table editor

This section describes how to edit an existing table. The following steps will add a primary key to a table created in the previous section named office. This will be accomplished by turning a column named office_id into a primary key. This column holds a numerical ID for each office.

 To edit an existing table using the table editor:

1	In the left panel, select the office table. You may have to expand the server, database and the Tables containers to view the office table.

2	Using the right mouse button, click on the selected office table to display the pop-up menu for the table object and select the Edit Columns menu item (the same menu item is also available under File menu on the menu bar). This causes the table editor to appear, displaying one row for every column in the table.

3	Click once on the office_id row, under the Key column. The icon changes to show the column named office_id is now also the primary key for the table named office.

Primary key conditions—If a check box appears under Allow Nulls column, or if duplicate values are stored in the office_id column, the column cannot be changed to a primary key.

4	Click the Save toolbar button to commit the changes to the office table. Pausing the mouse above a toolbar button causes a ToolTip to appear to more easily identify toolbar buttons.

5	Click the Add Column toolbar button to create another row in the table editor grid. This adds another column in the office table.

6	Edit the properties of the new column so that it's name is office_name, its type is char, its size is 20 and its value can be equal to null.

7	Click the Save and Close toolbar button to commit the changes and close the table editor.

The column is now present in the database, although it has no data. Sybase Central does not include facilities for data entry.


Dragging a column to a new table using Sybase Central
User's Guide

PART 2. Tutorials

CHAPTER 4. Managing Databases with Sybase Central

Adding a table to a database

Dragging a column to a new table using Sybase Central

This section describes how to add a column to the office table created in a previous section to hold the address of each office. The customer table in the same sample database already has an address column, which can be copied and added to the office table. These steps will copy the attributes, including the name, of a column in one table to another table, but will not copy data from one table to another.

 To drag a column to a table:

1	In the left panel, click and expand the customer table to expose the Columns folder. You may have to expand the database container and the Tables folder to do this.

2	Select the Columns folder. The right panel will adjust to display the columns in the customer table.

3	Click the address column in the right panel, and drag it to the office table in the left panel. The Copy Column Definition window is displayed.

4	Click OK to add the column to the office table. It will have the same attributes as the address column of the customer table but will contain no data.

5	To see the new column, select and expand the office table in the left panel, then select the Columns folder. The right panel will display the columns of the office table. The newly-added address column should be visible in the right panel.

6	To see the attributes of the address column, double-click the address column in the right panel. The address properties sheet appears.

7	Change the name of the column to office_address by typing this in the Name text box. This modification applies to the address column of the office table only. Once a column has been copied there is no longer any connection between the original column and the new column.

Notes

♦	Drag and drop is available for several kinds of database management task. For example, you can add users to user groups by dragging, or drag a table to another table to create a foreign key relationship. For a complete list of drag-and-drop operations, look up drag and drop summary in the Sybase Central online help.

♦	Property sheets are used extensively in Sybase Central. For example, property sheets are used for users, stored procedures and individual columns.

♦	Add Object icons are used to add other objects besides tables to a database. Stored procedures, triggers, indexes, users, user groups, and columns are among the database objects that you can add with an Add Object icon.

♦	Pop-up menus are available throughout the Sybase Central interface by clicking on objects or in windows using the right mouse button. Showing an object's pop-up menu is a convenient way of finding out what actions can be carried out on an object.


Deleting tables using Sybase Central
User's Guide

PART 2. Tutorials

CHAPTER 4. Managing Databases with Sybase Central

Adding a table to a database

Deleting tables using Sybase Central

Tables can be deleted, or dropped, from a database. The office table created in a previous section can be dropped from the sample database, restoring the database to its original state.

 To delete the office table from the sample database:

1	Using the right mouse button, click the office table.

2	Select Delete from the pop-up menu.


Viewing and editing procedures
User's Guide

PART 2. Tutorials

CHAPTER 4. Managing Databases with Sybase Central

Viewing and editing procedures

Stored procedures are kept in a folder within the database container object. This tutorial shows how to view and alter the contents of a procedure, and how to create new procedures using the Sybase Central code editor.

The Sybase Central code editor is a separate window for displaying and editing the code of triggers, procedures, and views.

Beyond text-editing functions, it provides:

♦	Automatic syntax highlighting.

♦	Automatic formulation of DDL statements.

♦	Unlimited Undo and Redo.

♦	Ability to find and replace text, and to jump to specific line numbers.

♦	Ability to execute the DDL code against the database.

 Viewing stored procedure code with Sybase Central


Viewing stored procedure code with Sybase Central
User's Guide

PART 2. Tutorials

CHAPTER 4. Managing Databases with Sybase Central

Viewing and editing procedures

Viewing stored procedure code with Sybase Central

There are several stored procedures included in the sample database. The following steps explain how to view and edit stored procedures.

 To view the contents of a procedure:

1	Select the Procedures & Functions folder from the sample database in the left panel. You may have to expand the database container to do this.

2	In the right panel, double-click sp_customer_list in the right panel. The Sybase Central code editor appears, displaying the text of the procedure.

3	A call to this procedure returns a set of customer IDs and company names from the Customer table.

Viewing procedures in Watcom-SQL or Transact-SQL

SQL Anywhere supports two alternative syntaxes for stored procedures. The native SQL Anywhere syntax (Watcom-SQL) is based on the ISO draft standard. SQL Anywhere also supports the Sybase Transact-SQL syntax. You can enter procedures in either syntax, and SQL Anywhere can automatically translate between the two syntaxes.

Not all procedure statements may translate. Untranslated statements appear as comments in the translated procedure.

 To view the alternative syntaxes of a procedure:

1	With the right mouse button, click on the sp_customer_list procedure. A pop-up menu appears.

2	Click Open to view the procedure in the syntax in which it was entered. This is the syntax in which the procedure is stored in the database.

3	Click Open as Watcom-SQL to view the procedure in Watcom-SQL syntax.

4	Click Open as Transact-SQL to view the procedure in Transact-SQL syntax.

Notes

♦	The Sybase Central code editor is used to display and create views and triggers as well as stored procedures.

Setting permissions on procedures

Stored procedures have permissions associated with them. In order to execute a procedure you either need to be granted permission to execute a procedure, or you need to be a member of a user group that has permission to execute the procedure.

 To view and alter the permissions on a procedure:

1	Using the right mouse button, click on the sp_customer_list procedure. A pop-up menu appears.

2	Select Properties from this menu. The properties sheet for sp_customer_list appears.

3	Click the Permissions tab to see which user IDs have been granted permissions on this procedure. Currently none do, as the only user for the sample database is DBA, who automatically has execute permissions as owner of the procedure.

4	Click the Grant Permissions button tab to grant users or groups permission to execute this procedure. Grant permission to execute this procedure to the Public user group by selecting the Public user group icon and clicking the Grant Permission button.

5	Click the OK button to accept the changes to the sp_customer_list permissions or Cancel to undo the changes.


Managing users and groups
User's Guide

PART 2. Tutorials

CHAPTER 4. Managing Databases with Sybase Central

Managing users and groups

In SQL Anywhere, both users and groups are objects within the database. However, groups are also containers, capable of containing users (making users a member of that group) and other groups.

In this structure, permissions granted to a group are inherited by those users and groups which have membership in the group. SQL Anywhere allows you to create users and groups permitted to use a database and grant membership to groups.

This tutorial demonstrates how to create a group for the database, create an individual user, and make the user a member of the group.

 Adding a group to the database

 Adding a user to the database

 Adding a user to a group


Adding a group to the database
User's Guide

PART 2. Tutorials

CHAPTER 4. Managing Databases with Sybase Central

Managing users and groups

Adding a group to the database

In this section we add a sales group to the sample database.

 To add a group to a database:

1	Select the Users & Groups folder in the left panel. You may need to expand the sample database container in the left panel to do this.

2	Double-click Add Group in the right panel. The New Group wizard appears.

3	Type the name Sales in the top text box. This is the name of the user group.

4	Enter a password (for example, Sales), confirm it by entering it again, and click Next to show the following page of the wizard.

5	Check the Resource authorities option, and uncheck the DBA and Remote DBA option, for this group.  Then click Next to show the following page of the wizard.

6	Click Finish to create the new group.

The sales group appears in both panels. Groups are container objects, and so appear in the left panel.


Adding a user to the database
User's Guide

PART 2. Tutorials

CHAPTER 4. Managing Databases with Sybase Central

Managing users and groups

Adding a user to the database

This section describes how to add a user to a database.

 To add a new user to the sample database:

1	Select the Users & Groups folder in the left panel. You may need to expand the sample database container in the left panel to do this.

2	Double-click Add User in the right panel. The new user wizard appears.

3	Type the name Sandy in the top text box. This is the user ID for the new user.

4	Type a password, and confirm it by retyping it. For example, you could use the password Sandy. Click OK to confirm the entries.

5	Follow the instructions to complete the wizard choosing the default options.

6	An icon appears in the right panel, showing the new user. There is no icon in the left panel, as individual user ID's are not containers.


Adding a user to a group
User's Guide

PART 2. Tutorials

CHAPTER 4. Managing Databases with Sybase Central

Managing users and groups

Adding a user to a group

Sybase Central provides two ways to add a user to a group. You can use the individual user's Properties sheet, which has a Membership tab. Or you can use a drag and drop method.

In this section we add two users to a group using drag and drop.

 To add users to a group:

1	Ensure that the Sales group is shown in the left panel and that the users DBA and Sandy are shown in the right panel. You may need to select the Users & Groups folder to do this.

2	Click Sandy to select this user.

3	While holding down the Ctrl key, click DBA to select this user as well.

4	Click and drag the users to the Sales group in the left or right panel.

5	Select the Sales group in the left panel to show its members.

Restoring the sample database to its original state

To restore the database to its original state, you can delete the Sales group and the user Sandy. For each of the two icons:

♦	Using the right mouse button, click the icon.

♦	Select Delete from the pop-up menu.


Backing up a database using Sybase Central
User's Guide

PART 2. Tutorials

CHAPTER 4. Managing Databases with Sybase Central

Backing up a database using Sybase Central

Sybase Central includes a set of database utilities for carrying out common database administration tasks. Wizards are provided to help carry out the task step-by-step.

To see all the database utilities provided with Sybase Central, click the Database Utilities folder at the top of the left panel. A list of the utilities appears in the right panel.

Some of the utilities are used on database files, while others can be used with running databases. Those utilities that can be used on a running database are shown on a pop-up menu by right mouse clicking on the database icon. In this lesson, we back up the sample database.

 To back up a running database

1	Using the right mouse button, click the sample database and select Backup from the pop-up menu. The Backup Wizard appears.

2	You do not need to alter anything on the first page of the wizard. Click Next to move to the second page.

3	You should already have the user ID DBA filled in, together with the password.  Click Next to move to the next page of the wizard.

4	Type a directory in the text box indicating where you wish to back up the database to. As this is a tutorial only, you may wish to choose a temporary file directory such as C:\TEMP.

5	Check the Main Database File and Transaction Log File options, and uncheck the Database Write File option. Then click Next to take you to the next page of the Wizard.

6	Select the bottom option button from the three options presented, and click Next to take you to the next page of the Wizard.

7	Review the choices you have made, and click Finish to back up the database. A window displays the progress of the backup.

Wizards are available for several other database administration tasks. You may wish to try creating a database by selecting the Database Utilities folder in the left panel and then double-clicking the Create Database tool in the right panel.


Using the Sybase Central online help
User's Guide

PART 2. Tutorials

CHAPTER 4. Managing Databases with Sybase Central

Using the Sybase Central online help

The main documentation for Sybase Central is available as online help separate from the SQL Anywhere User's Manual. This tutorial introduces you to the Sybase Central online help.

The online help is presented as a set of topics. You can find topics about a subject of interest using the Contents, the Index, or by searching the text of the online Help.

 Using the online help Contents

 Using the online help Index

 Searching the text of the online help


Using the online help Contents
User's Guide

PART 2. Tutorials

CHAPTER 4. Managing Databases with Sybase Central

Using the Sybase Central online help

Using the online help Contents

 To see the Sybase Central online help contents:

1	Select Help Topics from the Sybase Central Help menu. The Sybase Central online help Help Topics window appears.

2	The Help Topics window has three tabs: Contents, Index, and Find. Click the Contents tab.

The online help Contents are displayed as a set of books. To open a book, click the book and click Open. The following example illustrates the organization of the help topics.

 To find out how to add a group:

1	With the Contents tab showing on the Help Topics window, click Managing Users & Groups to open the book.

2	Click Creating A New User Or Group to display the topic.

Notes

♦	Many topics have a Related Topics link at the end of the topic, which can take you to related topics in the Sybase Central online help and in the online version of this book.

♦	You can use the Browse buttons (with arrows) to take you back and forward through related topics.

♦	You can configure some aspects of the appearance of the online help by clicking Options.

♦	Clicking Help Topics opens the Help Topics window again.

♦	Clicking SQL Anywhere 5.0 Help opens the online SQL Anywhere User's Guide.

You should spend some time browsing through the Contents window to familiarize yourself with the online help organization.


Using the online help Index
User's Guide

PART 2. Tutorials

CHAPTER 4. Managing Databases with Sybase Central

Using the Sybase Central online help

Using the online help Index

The Index provides an alternative way to search for information in the online Help.

This section shows how to find information about creating users using the index.

 To find a topic using the Index:

1	Open the Help Topics window, and click the Index tab.

2	Type "users" in the box numbered 1. In box 2, the Users & Groups index entry is highlighted.

3	The index is a two-level index. Click Creating under Users & Groups, and click Display to show the topic.

Notes

If there is more than one topic indexed under the entry you display, a list of topics is displayed.


Searching the text of the online help
User's Guide

PART 2. Tutorials

CHAPTER 4. Managing Databases with Sybase Central

Using the Sybase Central online help

Searching the text of the online help

If you cannot find the information you are looking for using the Contents or the Index, you may want to try searching the text of the online Help.

 To find a topic by searching text:

1	Open the Help Topics window, and click the Find tab.

2	When you have built your word list, type "user" in the box numbered 1. As you type, a list of matching words is shown in the box numbered 2.

3	Click user in box 2.

4	Click Creating A New User Or Group in the topic list in box number 3, and click Display to show the topic.


Using ISQL
User's Guide

PART 2. Tutorials

CHAPTER 5. Using ISQL

About this chapter

This chapter discusses how to run ISQL (Interactive SQL) under Microsoft Windows, Microsoft Windows NT, or IBM OS/2. Ideally, you should run the software on your computer as you work through this chapter.

This chapter presents the various facilities offered by the ISQL environment. The chapter "Selecting Data from Database Tables" starts an in-depth tutorial of the SQL language and the SQL Anywhere database engine.

 The SQL Anywhere program group

 Starting SQL Anywhere

 Connecting to the sample database from ISQL

 Accessing Help from ISQL

 The ISQL command window

 Leaving ISQL

 Displaying data in ISQL

 Command recall in ISQL

 Function keys

 Canceling an ISQL command

 What's next?


The SQL Anywhere program group
User's Guide

PART 2. Tutorials

CHAPTER 5. Using ISQL

The SQL Anywhere program group

After the software is installed, you will have a SQL Anywhere program group, containing icons for the components of the SQL Anywhere software (the SQL Anywhere client installation gives a subset of these icons). The program group for Windows 95 is displayed in the figure:


Starting SQL Anywhere
User's Guide

PART 2. Tutorials

CHAPTER 5. Using ISQL

Starting SQL Anywhere

Start the database engine on the sample database by double clicking on the SQL Anywhere icon labeled Standalone Sample Database.

The SQL Anywhere window appears displaying some startup information. After a few seconds, the window automatically reduces to an icon on the bottom of the screen.

Once the database engine is running, start ISQL by double clicking on the ISQL icon. The ISQL window appears.


Connecting to the sample database from ISQL
User's Guide

PART 2. Tutorials

CHAPTER 5. Using ISQL

Connecting to the sample database from ISQL

When you start ISQL, it is not connected to any database. When a database is running, ISQL displays the SQL Anywhere Log On window.

♦	You must enter a number of connection parameters in the Connection window.

♦	User ID   For the sample database, use the user ID dba.

♦	Password   The password for the dba user ID is sql.

The password does not appear when you type it. This prevents someone else from seeing your password

♦	The connect dialog contains a button labeled More>>. Click More>>  to reveal a larger dialog box which contains more options for connecting to databases. These options are not needed for connecting to a database when only one database is running. (For the purposes of this tutorial, the options revealed by clicking More are not needed).

♦	After entering the user ID and password, press ENTER (or click OK) to connect to the sample database.

If you have made typing mistakes or the sample database is not found, an error message appears. You can use the tab key to move to the field in error and correct the problem using the cursor keys and the backspace key.

After connecting to the database, ISQL displays the database name, user ID, and server name for the connection on the title bar.


Accessing Help from ISQL
User's Guide

PART 2. Tutorials

CHAPTER 5. Using ISQL

Accessing Help from ISQL

Help is available by pressing the F1 key, or by choosing Help [image] Help from the menu bar. The Help system can also be activated with the HELP command. The Help files contain help on many topics—most of this manual is contained in the Help files.

For more information on using Help, choose Help [image] Using Help from the menu bar.


The ISQL command window
User's Guide

PART 2. Tutorials

CHAPTER 5. Using ISQL

The ISQL command window

The Command window appears at the bottom of the ISQL screen. It is a standard edit control for typing ISQL commands. If more lines are typed than will fit in this window, the window automatically scrolls. You can scroll the window using the cursor keys or the scroll bar on the right side of the window. This window can also be made larger and maximized to full screen size in the standard Windows or OS/2 fashion.

Commands are executed by pressing the execute key (F9) or you can click the Execute button.

Multiple commands can be entered at once by separating them with semicolons. Commands can be stored to an ASCII file or loaded from an ASCII file by choosing File [image] Save or Open from the menu bar.


Leaving ISQL
User's Guide

PART 2. Tutorials

CHAPTER 5. Using ISQL

Leaving ISQL

When you have finished working with ISQL, the EXIT command returns you to the operating system (or choose File [image] Exit from the menu bar). You can then stop the database engine by clicking on the SQL Anywhere icon and selecting the Close menu item.

If you leave ISQL now, you will have to restart ISQL to continue with the tutorial.


Displaying data in ISQL
User's Guide

PART 2. Tutorials

CHAPTER 5. Using ISQL

Displaying data in ISQL

One of the principal uses of ISQL is to look at information in databases.

The database used in this tutorial is for a fictional company. The sample database contains information about employees, departments, sales orders, and so on.

All this information is organized into a number of tables, consisting of rows and columns.

You display information from a database using the SELECT statement. The following example shows the command to type in the ISQL command window. Once you have typed the command, you must click Execute to carry out the command. The example displays the first several columns and rows of the results of the query, which are displayed in the ISQL data window. The format is used throughout this manual.

 To list all the columns and rows of the employee table:

1	Type the following:

SELECT *

FROM employee

emp_id	manager_id	emp_lname	emp_fname	...
102	501	Fran	Whitney	...
105	501	Matthew	Cobb	...
129	902	Philip	Chin	...
148	1293	Julie	Jordan	...
160	501	Robert	Breault	...
...
Notes

♦	SQL statements are case insensitive. SELECT is the same as select is the same as Select. In the examples, SQL keywords are shown in upper case, but you do not have to type them in upper case.

♦	SQL statements can be typed on more than one line. You can type the statements all on one line, or break them over several lines as you wish. 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, but you do not have to type them this way.

The ISQL Data window displays a set of rows and columns containing information about the employees. Each row contains information about one employee, and each column contains a particular piece of information for all employees.

 Scrolling the data window


Scrolling the data window
User's Guide

PART 2. Tutorials

CHAPTER 5. Using ISQL

Displaying data in ISQL

Scrolling the data window

When you type the command

SELECT * FROM employee

in the ISQL command window, the visible portion of the ISQL data window cannot hold the entire employee table.

The visible portion of the data window does not display all the information about each employee, and does not display the entire list of employees.

Viewing other columns

To see more information about each employee (that is, other columns) you use the scroll bar at the bottom of the data window. This is a standard Windows or OS/2 scroll bar.

Viewing other rows

To see more information on other employees (that is, other rows), use the scroll bar to the right of the data window. The employee table in the sample database has information on about 75 employees.

Sometimes, the vertical scroll bar behaves slightly differently than standard scroll bars, as the number of rows in the result may be unknown. In this case, a guess as to the number of rows is used. If ISQL determines that its guess is wrong, the guess is adjusted and the slider "jumps".


Command recall in ISQL
User's Guide

PART 2. Tutorials

CHAPTER 5. Using ISQL

Command recall in ISQL

Let's execute another command.

♦	Type the following:

SELECT * FROM department

♦	Press F9.

The contents of the department database table are displayed in the Data window. As you execute commands with ISQL, they are saved in a command history. To recall commands, choose Command [image] Recall from the menu bar. This activates the command recall window.

The command recall window displays the first line of the last 15 commands executed. Use the cursor up and down keys to scroll through the commands.

Position the cursor on the first command that you executed, which was:

SELECT *

FROM employee

and press the ENTER key. The cursor returns to the command window with the selected command in it. You can now re-execute that command or modify it to make a new command.

More recall keys

The following keys can also be used to recall previous commands:

Key sequence	Description
CTRL+R	Brings  up the command recall window
CTRL+P	Cycles backwards through previously executed commands. Retrieved commands are placed into the command window
CTRL+N	Cycles forward through previously executed commands


Function keys
User's Guide

PART 2. Tutorials

CHAPTER 5. Using ISQL

Function keys

ISQL uses some function keys and special keys as follows:

Function key	Description
F1	Help
F5	Move data to the left by one column in the data window
SHIFT+F5	Move data to the left by one character
F6	Move data to the right by one column
SHIFT+F6	Move data to the right by one character
F7	Display a list of the tables in the database. The cursor up and down keys can be used to scroll through the table names changing the highlighted table name. With the list displayed, pressing ENTER will insert the current table name into the command window at the cursor position. The F7 key can be used while the table list is displayed, and a list of columns will be displayed for the highlighted table. Again, ENTER can be used to select the highlighted column name and put it into the command window at the cursor position.
F9	Execute the command that is in the command window. This operation can also be performed with the mouse by clicking Execute.
F10	Activate the menus
PGUP	Move data up a page
PGDN	Move data down a page
CTRL+PGUP	Move to top of data
CTRL+PGDN	Move to bottom of data


Canceling an ISQL command
User's Guide

PART 2. Tutorials

CHAPTER 5. Using ISQL

Canceling an ISQL command

The Stop button is used to cancel a command.

A Stop operation stops current processing and prompts for the next command. If a command file was being processed, you are prompted for an action to take (Stop command file, Continue, or Exit ISQL). These actions can be controlled with the ISQL ON_ERROR option (see "SET OPTION statement").

Reported errors

When an abort is detected, one of three different errors will be reported depending upon when the abort is detected.

♦	If the abort is detected when ISQL is processing the request (as opposed to the database engine), then the following message is displayed:

ISQL command terminated by user

stops processing immediately and the database transaction is left alone.

♦	If the abort is detected while the database engine is processing a data definition command (CREATE, DROP, ALTER, etc.), 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 engine is running in bulk operations mode executing a command that modifies the database (INSERT, UPDATE, and 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 engine to perform the automatic ROLLBACK.

♦	If the cancel is detected by the database engine while processing a standard data manipulation command (SELECT, INSERT, DELETE, etc.) and the engine is not running in bulk operations mode, then the following message is displayed.

Statement interrupted by user.

The effects of the current command are undone, but the rest of the transaction is left intact.


What's next?
User's Guide

PART 2. Tutorials

CHAPTER 5. Using ISQL

What's next?

Once you are familiar with the basics of ISQL, you should proceed to the chapter "Selecting Data from Database Tables" for a tutorial on the SQL language.


Using Character-Mode ISQL
User's Guide

PART 2. Tutorials

CHAPTER 6. Using Character-Mode ISQL

About this chapter

This chapter discusses how to run ISQL (Interactive SQL) under those operating systems for which a character-mode ISQL is provided: DOS, QNX, or NetWare.

You should actually run the software on your computer as you work through this chapter. This chapter presents the various facilities offered by the ISQL environment.

 Tutorial files

 Starting the SQL Anywhere software

 Connecting to the sample database from ISQL

 ISQL menu selection

 Obtaining help from ISQL

 The ISQL command window

 Leaving ISQL

 Displaying data in ISQL

 Command window keys in ISQL

 Scrolling the data window

 Command recall in ISQL

 Function keys

 Aborting an ISQL command

 What next?


Tutorial files
User's Guide

PART 2. Tutorials

CHAPTER 6. Using Character-Mode ISQL

Tutorial files

DOS: First, you should be in the subdirectory containing the SQL Anywhere software. This directory is chosen at installation time (usually C:\SQLANY50). The commands

c:

cd \sqlany50\dos

will get you there. The sample database, SADEMO.DB, will be located in the parent directory (C:\SQLANY50).

Alternatively, you may want to copy the sample database used in this tutorial into a different working directory. The only file you need to copy is: SADEMO.DB. In this case, you need to have SQL Anywhere in your PATH (this is done for you at installation time).

QNX: copy or link the sample database to a working directory—You should copy the sample database to your working directory or create a link to it. For example,cp /usr/lib/sqlany50/sample/sademo.db .

orln /usr/lib/sqlany50/sample/sademo.db .


Starting the SQL Anywhere software
User's Guide

PART 2. Tutorials

CHAPTER 6. Using Character-Mode ISQL

Starting the SQL Anywhere software

To start ISQL in DOS or QNX, type the command:

isql

To start ISQL on a NetWare machine, type the command:

load isql.nlm

This command loads ISQL.


Connecting to the sample database from ISQL
User's Guide

PART 2. Tutorials

CHAPTER 6. Using Character-Mode ISQL

Connecting to the sample database from ISQL

ISQL initially is not connected to any database. To connect, type the command

connect

and press the Execute key.

ISQL prompts you for a number of connection parameters. These include a user identification (user ID), password and database file Type the user ID DBA, then press the TAB key to move to the next field.

Type in the password SQL. The password does not appear when you type it. This prevents someone else from seeing your password.

Press the TAB key again to move to the database file field and enter SADEMO.DB. This is the sample database that you will use in the tutorial.

Now press the ENTER key (or click the OK button using a mouse) to connect to the database. If you have made typing mistakes or the sample database is not found, an error message will appear. You can use the tab key to move to the field in error and correct the problem using the cursor keys and the backspace key.

If you have typed everything correctly, the problem could be that the database SADEMO.DB is not in your current directory. You should return to the beginning of this chapter, making sure that the software has been installed correctly and that you have followed the instructions in "Tutorial files".

If you successfully connect to the database, the statistics window displays the message Connected to database.


ISQL menu selection
User's Guide

PART 2. Tutorials

CHAPTER 6. Using Character-Mode ISQL

ISQL menu selection

Throughout this book, you will be instructed to choose items from pull-down menus. The pull-down menus are located at the top of the screen.

To illustrate their use, we will choose Help from the Help menu. :option.

 To choose a menu item using the keyboard:

1	Press the ALT key.

2	Press the highlighted letter in the name of the menu (H). The Help menu will "pull down".

3	Press the highlighted letter in the name of the item (H).

 To choose a menu item using the mouse:

1	Position the mouse on the name of a pull-down menu (Help).

2	Press and release (click) the left mouse button. The Help menu will "pull down".

3	Position the mouse on the correct item and click the left mouse button again.

To leave the Help system, press the ESCAPE key, or click on the Cancel button.


Obtaining help from ISQL
User's Guide

PART 2. Tutorials

CHAPTER 6. Using Character-Mode ISQL

Obtaining help from ISQL

Help is available by pressing the F1 key, or by choosing Help from the Help menu. The help system can also be activated with the HELP command. The help files contain help on many topics — most of this manual is contained in the help files.


The ISQL command window
User's Guide

PART 2. Tutorials

CHAPTER 6. Using Character-Mode ISQL

The ISQL command window

The command window appears at the bottom of the screen. It has four lines for typing ISQL commands. If more than 4 lines are typed, the window scrolls automatically. You can scroll the window using the cursor keys or the scroll bar on the right side of the window. This window can also be made larger and zoomed to full screen size by choosing the appropriate item from the Command menu.

Grow Window (CTRL+G) to grow window one line up to a maximum of half the screen.

Shrink Window (CTRL+S) to shrink window one line down to a minimum of 3 lines.

Zoom Window (CTRL+Z) to zoom window to full screen and back again.


Leaving ISQL
User's Guide

PART 2. Tutorials

CHAPTER 6. Using Character-Mode ISQL

Leaving ISQL

When you have finished working with ISQL, the EXIT command returns you to the operating system (or choose Exit from the File menu). Since ISQL started the database engine, the database engine is automatically stopped by ISQL on exit. If you exit from ISQL, you will have to start ISQL again to continue with the tutorial.


Displaying data in ISQL
User's Guide

PART 2. Tutorials

CHAPTER 6. Using Character-Mode ISQL

Displaying data in ISQL

One of the principal uses of ISQL is to look at information in databases.

The database used in this tutorial is for a fictional company. The sample database contains information about employees, departments, sales orders, and so on.

All this information is organized into a number of tables, consisting of rows and columns.

You display information from a database using the SELECT statement. The following example shows the command to type in the ISQL command window. Once you have typed the command, you must click Execute to carry out the command. The example displays the first several columns and rows of the results of the query, which are displayed in the ISQL data window. The format is used throughout this manual.

 To list all the columns and rows of the employee table:

1	Type the following statement:

SELECT *cd2

FROM employee

emp_id	manager_id	emp_lname	emp_fname	...
102	501	Fran	Whitney	...
105	501	Matthew	Cobb	...
129	902	Philip	Chin	...
148	1293	Julie	Jordan	...
160	501	Robert	Breault	...
...
Notes

♦	SQL statements are case insensitive. SELECT is the same as select is the same as Select. In the examples, SQL keywords are shown in upper case, but you do not have to type them in upper case.

♦	SQL statements can be typed on more than one line. You can type the statements all on one line, or break them over several lines as you wish. 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, but you do not have to type them this way.

The ISQL Data window displays a set of rows and columns containing information about the employees. Each row contains information about one employee, and each column contains a particular piece of information for all employees.


Command window keys in ISQL
User's Guide

PART 2. Tutorials

CHAPTER 6. Using Character-Mode ISQL

Command window keys in ISQL

If you make a spelling mistake, you can correct it using the following keys:

CURSOR LEFT    moves the cursor left over top of any characters already typed.

CURSOR RIGHT   moves the cursor right.

HOME   moves the cursor to the start of the line.

END   moves the cursor past the last character of the line.

INS   toggles Insert mode. When Insert mode is on, the cursor is different (usually fatter), and any characters typed will be inserted where the cursor is, pushing characters to the right of the cursor further to the right.

DEL   deletes the character at the cursor, and moves the rest of the line back to fill the vacant position.

BACKSPACE   deletes the character immediately to the left of the cursor. If this key is pressed at the beginning of a line, it will join the current line to the previous one.

CTRL+END   erases from the cursor position to the end of the line.

ENTER   moves the cursor to the beginning of the next line.

CURSOR DOWN   moves the cursor down one line. If you are on the last line of the command window and there are more lines below the window, the text will scroll up one line so that you can see the next line.

CURSOR UP   moves the cursor up one line. If you are on the first line of the command window and there are more lines above, the text will scroll down one line so that you can see the previous line.

ESC   clears the entire command from the command window.

SHIFT+CURSORUP, SHIFT+CURSORDOWN, SHIFT+PGUP, SHIFT+PGDN   used to mark an area (set of lines). This can also be done by pressing the left mouse button and holding it down while you drag the mouse over the lines to be marked.

CTRL+X   cuts the marked area to the edit clipboard. The lines are removed from the current position and can be pasted back anywhere using the Ctrl+V key combination.

CTRL+V    pastes the contents of the edit clipboard into position following the current line.

CTRL+C   copies the marked area to the edit clipboard. This is different than the CTRL+X key combination in that it does not delete the marked area. There are also items in the Edit menu that can be used instead of these key combinations.

The following keys are also useful shortcut keys, but they will only work on newer keyboards.

ALT+INS   insert a new line after the current line.

ALT+DEL   delete the current line.

Commands are executed by pressing the execute key (F9). The right mouse button also executes the current command.

Multiple commands can be entered at once by separating them with semicolons. Commands can be stored to an ASCII file or loaded from an ASCII file by choosing Save or Open from the File menu.


Scrolling the data window
User's Guide

PART 2. Tutorials

CHAPTER 6. Using Character-Mode ISQL

Scrolling the data window

When you type the command

SELECT * FROM employee

in the ISQL command window, the visible portion of the ISQL data window cannot hold the entire employee table.

The visible portion of the data window does not display all the information about each employee, and does not display the entire list of employees.

To see more information about each employee (that is, other columns) you use the move left and move right operations. These operations can be done by choosing Left and Right from the Data menu. If your computer has a mouse, you can also move right by using the scroll bar at the bottom of the data window.

The employee table in the sample database has information on 75 employees. To see more information on other employees (that is, other rows), use the PAGE DOWN and PAGE UP keys. Try pressing the PAGE DOWN key, and observe that a new screen full of employees is shown. Continue pressing PAGE DOWN. and eventually the screen contains only the column names with no rows. Pressing PAGE UP. at this point will bring back the last screen full of employees in the employee table.

If your computer has a mouse, you can also move the information up and down using the scroll bar on the right side of the screen. Sometimes, this scroll bar behaves slightly differently than standard scroll bars when the number of rows in the result is unknown. In this case, a guess as to the number of rows is used. When ISQL determines that the guess is wrong, it will be adjusted and the slider "jumps".

The Data menu contains items for moving up and down a line. It also has items for going to the top and bottom of the query. These actions can also be performed with CTRL+PAGE DOWN and CTRL+PAGE UP. CTRL + PAGEG DOWN is actually two keys; hold down the CTRL key and press the PAGE DOWN key. When you do this, ISQL displays the last screen of employees in the employee table. Similarly, CTRL+PAGE UP will display the first screen of employees. You can move back to the original position by using CTRL+PAGE UP and then pressing the Left Arrow key until the emp_id column appears.


Command recall in ISQL
User's Guide

PART 2. Tutorials

CHAPTER 6. Using Character-Mode ISQL

Command recall in ISQL

Let's execute another command. Type the following and then press &doit.:

SELECT *FROM department

The contents of the department database table are displayed in the Data window. As you execute commands with ISQL, they are saved in a command history. To recall commands, choose Recall from the Command menu. This activates the command recall window. The window displays the first line of the last 15 commands that you have executed. Use the cursor up and down keys to scroll through the commands. As you do so, the full command appears in the command window at the bottom of the screen.

Position the cursor on the first command that you executed, which was:

SELECT *FROM employee

Now press the ENTER key. The cursor will return to the command window with that command in it. You can now re-execute that command or you can modify it to make a new command.

The following keys can also be used to recall previous commands:

CTRL+R bring up the command recall window.

CTRL+P cycles backwards through previously executed commands. Retrieved commands are placed into the command window.

CTRL+N cycles forward through previously executed commands.


Function keys
User's Guide

PART 2. Tutorials

CHAPTER 6. Using Character-Mode ISQL

Function keys

ISQL uses some function keys and special keys as follows:

F1   Help.

F5    Move data to the left by one column in the data window.

Shift+F5   Move data to the left by one character.

F6   Move data to the right by one column.

Shift+F6   Move data to the right by one character.

F7   Display a list of the tables in the database. The cursor up and down keys can be used to scroll through the table names changing the highlighted table name. With the list displayed, pressing &enter. will insert the current table name into the command window at the cursor position. The :key.F7:ekey. key can be used while the table list is displayed, and a list of columns will be displayed for the highlighted table. Again, &enter. can be used to select the highlighted column name and put it into the command window at the cursor position.

F9   Execute the command that is in the command window. This operation can also be performed with the mouse by pressing the right mouse button or clicking Execute.

F10   Activate the menus.

PgUp   Move data up a page.

PgDn   Move data down a page.

Ctrl+PgUp   Move to top of data.

Ctrl+PgDn   Move to bottom of data.


Aborting an ISQL command
User's Guide

PART 2. Tutorials

CHAPTER 6. Using Character-Mode ISQL

Aborting an ISQL command

The CTRL+BREAK combination is used to abort a command.

A Stop operation stops current processing and prompts for the next command. If a command file was being processed, you are prompted for an action to take (Stop command file, Continue, or Exit ISQL). These actions can be controlled with the ISQL ON_ERROR option.

 For more information on ISQL options, see "SET OPTION statement".

When an abort is detected, one of three different errors will be reported depending upon when the abort is detected.

♦	If the abort is detected when ISQL is processing the request (as opposed to the database engine), then the following message is displayed:

ISQL command terminated by user

♦	ISQL stops processing immediately and the database transaction is left alone.

♦	If the abort is detected while the database engine is processing a data definition command (CREATE, DROP, ALTER, etc.), the following message is displayed: 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 engine is running in bulk operations mode executing a command that modifies the database (INSERT, UPDATE, and 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 engine to perform the automatic ROLLBACK.

♦	If the abort is detected by the database engine while processing a standard data manipulation command (SELECT, INSERT, DELETE, etc.) and the engine is not running in bulk operations mode, then the following message is displayed. Statement interrupted by user The effects of the current command are undone, but the rest of the transaction is left intact.


What next?
User's Guide

PART 2. Tutorials

CHAPTER 6. Using Character-Mode ISQL

What next?

Once you are familiar with the basics of ISQL, you should proceed to "Selecting Data from Database Tables" for a tutorial on the SQL language.


Selecting Data from Database Tables
User's Guide

PART 2. Tutorials

CHAPTER 7. Selecting Data from Database Tables

About this chapter

This tutorial introduces the SELECT statement, the statement you use to retrieve information from databases. SELECT statements are commonly called queries, because they ask the database engine about the information in a database.

Before you begin the tutorial—The SELECT statement is a versatile command. SELECT statements can become highly complex in applications retrieving very specific information from large databases. This tutorial uses only simple SELECT statements: more advanced queries are described in later tutorials.
  For more information about the full syntax of the select statement, see "SELECT statement".

Notes

Ideally, you should be running the SQL Anywhere software on your computer while you read and work through the tutorial lessons.

Each lesson instructs you to type commands into the computer 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.

This tutorial assumes that you have already started ISQL and connected to the sample database. If you have not already done so, see  the chapter "Using ISQL" or "Using Character-Mode ISQL".

 Looking at the information in a table

 Ordering query results

 Selecting columns from a table

 Selecting rows from a table

 Comparing dates in queries

 Compound search conditions in the WHERE clause

 Pattern matching in search conditions

 Matching rows by sound

 Short cuts for typing search conditions


Looking at the information in a table
User's Guide

PART 2. Tutorials

CHAPTER 7. Selecting Data from Database Tables

Looking at the information in a table

The database you use in this tutorial is for a fictional company. The database contains information about employees, departments, sales orders, and so on. All the information is organized into a number of tables.

Using the SELECT statement

In this lesson, you look at one of the tables in the database. The command used will look at everything in a table called employee. Execute the command:

SELECT * FROM Employee

Case sensitivity

The table name employee is shown starting with an upper case E, even though the real table name is all lower case. SQL Anywhere databases can be created as case-sensitive or case-sensitive in their string comparisons, but are always case insensitive in their use of identifiers. For information on creating databases, see the chapter "Initializing a database", or the description of the DBINIT command in the chapter "SQL Anywhere Components".

You can type select or Select instead of SELECT. SQL Anywhere allows you to type keywords in uppercase, lowercase, or any combination of the two. In this manual, uppercase letters are generally used for SQL keywords.

The SELECT statement retrieves all the rows and columns of the employee table, and the ISQL Data window lists those that will fit:

emp_id	manager_id	emp_fname	emp_lname	dept_id
102	501	Fran	Whitney	100
105	501	Matthew	Cobb	100
129	902	Philip	Chin	200
148	1293	Julie	Jordan	300
160	501	Robert	Breault	100
You will also see some information in the ISQL statistics window. This information is explained later.

The employee table contains a number of rows organized into columns. Each column has a name, such as emp_lname or emp_id. There is a row for each employee of the company, and each row has a value in each column. For example, the employee with employee ID 102 is Fran Whitney, whose manager is employee ID 501.

Manipulation of the ISQL environment is specific to the operating system you are running in.

For information on how to scroll the data and manipulate the ISQL environment, see the chapter "Using ISQL" or "Using Character-Mode ISQL".


Ordering query results
User's Guide

PART 2. Tutorials

CHAPTER 7. Selecting Data from Database Tables

Ordering query results

Unless otherwise requested, SQL Anywhere displays the rows of a table in no particular order. Often it is useful to look at the rows in a table in a more meaningful sequence. For example, you might like to see employees in alphabetical order.

The following example shows how adding an ORDER BY clause to the SELECT statement causes the results to be retrieved in alphabetical order.

 To list the employees in alphabetical order:

1	Type the following:

SELECT * FROM employee ORDER BY emp_lname

emp_id	manager_id	emp_fname	emp_lname	dept_id
1751	1576	Alex	Ahmed	400
1013	703	Joseph	Barker	500
591	1576	Irene	Barletta	400
191	703	Jeannette	Bertrand	500
1336	1293	Janet	Bigelow	300
Notes

The order of the clauses is important. The ORDER BY clause must follow the FROM clause and the SELECT clause.


Selecting columns from a table
User's Guide

PART 2. Tutorials

CHAPTER 7. Selecting Data from Database Tables

Selecting columns from a table

Often, you are only interested in some of the columns in a table. For example, to make up birthday cards for employees you might want to see the emp_lname, dept_id, and birth_date columns.

 List the last name, department, and birthdate of each employee:

1	Type the following:

SELECT emp_lname, dept_id, birth_date

FROM employee

emp_lname	dept_id	birth_date
Whitney	100	1958-06-05
Cobb	100	1960-12-04
Chin	200	1966-10-30
Jordan	300	1951-12-13
Breault	100	1947-05-13
Rearranging columns

The three columns appear in the order in which you typed them in the SELECT command. If you want to rearrange the columns, simply change the order of the column names in the command. For example, to put the birth_date column on the left, use the following command:

SELECT birth_date, emp_lname , dept_id

FROM employee

Ordering rows

You can order rows and look at only certain columns at the same time as follows:

SELECT birth_date, emp_lname , dept_id

FROM employee

ORDER BY emp_lname

As you might have guessed, the asterisk in

SELECT * FROM employee

is a short form for all columns in the table.


Selecting rows from a table
User's Guide

PART 2. Tutorials

CHAPTER 7. Selecting Data from Database Tables

Selecting rows from a table

Sometimes you will not want to see information on all the employees in the employee table. Adding a WHERE clause to the SELECT statement allows only some rows to be selected from a table.

For example, suppose you would like to look at the employees with first name John.

 List all employees named John:

1	Type the following:

SELECT *

FROM employee

WHERE emp_fname = 'John'

emp_id	manager_id	emp_fname	emp_lname	dept_id
318	1576	John	Crow	400
862	501	John	Sheffield	100
1483	1293	John	Letiecq	300
Apostrophes and case-sensitivity

♦	The apostrophes (single quotes) around the name  'John' are required. They indicate that John is a character string. Quotation marks (double quotes) have a different meaning. Quotation marks can be used to make otherwise invalid strings valid for column names and other identifiers.

♦	The sample database provided with SQL Anywhere is not case sensitive, so you would get the same results whether you searched for ' 'JOHN', 'john', or 'John'.

Again, you can combine what you have learned:

SELECT emp_fname, emp_lname, birth_date

FROM employee

WHERE emp_fname = 'John'

ORDER BY birth_date

Notes

♦	How you order clauses is important. The FROM clause comes first, followed by the WHERE clause, and then the ORDER BY clause. If you type the clauses in a different order, you will get a syntax error.

♦	You do not need to split the statement into several lines. You can enter the statement into the command window in any format. If you use more than the number of lines that fit on the screen, the text scrolls in the Command window.


Comparing dates in queries
User's Guide

PART 2. Tutorials

CHAPTER 7. Selecting Data from Database Tables

Comparing dates in queries

Sometimes, you will not know exactly what value you are looking for, or you would like to see a set of values. You can use comparisons in the WHERE clause to select a set of rows that satisfy the search condition. The following example shows the use of a date inequality search condition.

 To list all employees born before March 3, 1964"

1	Type the following:

SELECT emp_lname, birth_date

FROM employee

WHERE birth_date < 'March 3, 1964'

emp_lname	birth_date
Whitney	1958-06-05
Cobb	1960-12-04
Jordan	1951-12-13
Breault	1947-05-13
Espinoza	1939-12-14
Dill	1963-07-19
SQL Anywhere knows that the birth_date column contains a date, and converts 'March 3, 1964' to a date automatically.


Compound search conditions in the WHERE clause
User's Guide

PART 2. Tutorials

CHAPTER 7. Selecting Data from Database Tables

Compound search conditions in the WHERE clause

So far, you have seen equal (=) and less than (<) as comparison operators. SQL Anywhere also supports other comparison operators, such as greater than (>), greater than or equal (>=), less than or equal (<=), and not equal (<>).

These conditions can be combined using AND and OR to make more complicated search conditions.

 To list all employees born before March 3, 1964, but exclude the employee named Whitney:

1	Type the following:

SELECT emp_lname, birth_date

FROM employee

WHERE birth_date < '1964-3-3'

AND emp_lname <> 'whitney'

emp_lname	birth_date
Cobb	1960-12-04
Jordan	1951-12-13
Breault	1947-05-13
Espinoza	1939-12-14
Dill	1963-07-19
Francis	1954-09-12


Pattern matching in search conditions
User's Guide

PART 2. Tutorials

CHAPTER 7. Selecting Data from Database Tables

Pattern matching in search conditions

Another useful way to look for things is to search for a pattern. In SQL, the word LIKE is used to search for patterns. The use of LIKE can be explained by example.

 To list all employees whose last name begins with BR:

1	Type the following:

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.

 To list all employees whose surname begins with BR, followed by zero or more letters and a T, followed by zero or more letters:

1	Type the following:

SELECT emp_lname, emp_fname

FROM employee

WHERE emp_lna -me 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.

The pattern BR_U% matches all names starting with BR and having U as the fourth letter. In Braun the _ matches the letter A and the % matches N.


Matching rows by sound
User's Guide

PART 2. Tutorials

CHAPTER 7. Selecting Data from Database Tables

Matching rows by sound

With the SOUNDEX function, you can match rows by sound, as well as by spelling. 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?

 To list employees with surnames that sound like Brown:

1	Type the following:

SELECT emp_lname, emp_fname

FROM employee

WHERE SOUNDEX( emp_lname ) = SOUNDEX( 'Brown' )

emp_lname	emp_fname
Braun	Jane
Jane Braun is the only employee matching the search condition.


Short cuts for typing search conditions
User's Guide

PART 2. Tutorials

CHAPTER 7. Selecting Data from Database Tables

Short cuts for typing search conditions

Using the shortform BETWEEN

SQL has two short forms for typing in search conditions. The first, BETWEEN, is used when you are looking for a range of values. For example,

SELECT emp_lname, birth_date

FROM employee

WHERE birth_date BETWEEN '1965-1-1'

AND '1965-3-31'

is equivalent to:

SELECT emp_lname, birth_date

FROM employee

WHERE birth_date >= '1965-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 command

SELECT emp_lname, emp_id

FROM employee

WHERE emp_lname IN ('yeung','bucceri','charlton')

means the same as:

SELECT emp_lname, emp_id

FROM employee

WHERE emp_lname = 'yeung'

OR emp_lname = 'bucceri'

OR emp_lname = 'charlton'


Joining Tables
User's Guide

PART 2. Tutorials

CHAPTER 8. Joining 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.

 Displaying a list of tables

 Joining tables with the cross product

 Restricting a join

 How tables are related

 Join operators


Displaying a list of tables
User's Guide

PART 2. Tutorials

CHAPTER 8. Joining Tables

Displaying a list of tables

In the chapter "Selecting Data from Database Tables", you looked only at the employee table in the database. The sample database consists of nine tables, storing information about our fictional company.

Each box in the diagram represents a table in the database. The list of names in each box are the column names for the table.

In ISQL, you can display a list of tables by pressing the F7 key. The tables for the database are prefixed with dba (the owner of the tables).

The cursor keys can be used to scroll through the list of tables. Each table in the list is prefixed with a user name. This prefix is the ID of the user that created the table—the owner of the table.

Positioning the highlight on a particular table and pressing the Column List button displays the list of columns for that table. The ESCAPE key takes you back to the table list and pressing it again will take you back to the command window. Pressing ENTER instead of ESCAPE copies the highlighted table or column name into the command window at the current cursor position.

Press ESCAPE to leave the list.


Joining tables with the cross product
User's Guide

PART 2. Tutorials

CHAPTER 8. Joining Tables

Joining tables with 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.

You can get information from two tables at the same time by listing both tables in the FROM clause of a SELECT query.

Example

The following example lists all the data in the employee table and the sales_order table:

SELECT *

FROM sales_order, employee

The results of this query, displayed in the ISQL data window, 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 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.

The cross product join is a simple starting point for understanding joins, but not very useful in itself.


Restricting a join
User's Guide

PART 2. Tutorials

CHAPTER 8. Joining Tables

Restricting a join

The most natural way to make a join useful is to insist that the sales_rep in the sales_order table be 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 rep responsible for it.

Example 1

To do this, add a WHERE clause to the previous query to show the list of employees and their course registrations:

SELECT *

FROM sales_order, employee

WHERE sales_order.sales_rep = employee.emp_id

The table name is given as a prefix to identify the columns. Although not strictly required in this case, using the table name prefix clarifies the statement, and is required when two tables have a column with the same name. A table name used in this context is called a qualifier.

The results of this query contain only 648 rows (one for each row in the sales_order table). Of the original 48,600 rows in the join, only 648 of them have the employee number equal in the two tables.

Example 2

The following query is a modified version that fetches only some of the columns and orders the results.

SELECT employee.emp_lname, sales_order.id, sales_order.order_date

FROM sales_order, employee

WHERE sales_order.sales_rep = employee.emp_id

ORDER BY employee.emp_lname

If there are many tables in a SELECT command, you may need to type several qualifier names. This typing can be reduced by using a correlation name.

Correlation names

Correlation names are created by putting a short form for a table name immediately after the table name, separated by the word AS. The short form is then used as a qualifier instead of the corresponding table name, as follows:

SELECT E.emp_lname, S.id, S.order_date

FROM sales_order as S, employee as E

WHERE S.sales_rep = E.emp_id

ORDER BY E.emp_lname

Here, two correlation names S and E are created for the sales_order and employee tables.

If you try changing E.emp_id back to employee.emp_id, SQL Anywhere reports an error. If you make a correlation name for a table, you must use the correlation name when qualifying which table a column is from; you cannot use the original table name anymore.


How tables are related
User's Guide

PART 2. Tutorials

CHAPTER 8. Joining Tables

How tables are related

In order to understand how to construct other kinds of joins, you must first understand how the information in one table is related to that in another.

The primary key for a table identifies each row in the table. Tables are related to each other using a foreign key.

This section shows how primary and foreign keys together let you construct queries from more than one table.

 Rows are identified by a primary key

 Tables are related by a foreign key


Rows are identified by a primary key
User's Guide

PART 2. Tutorials

CHAPTER 8. Joining Tables

How tables are related

Rows are identified by a primary key

Every table in the employee database has a primary key. A primary key is one or more columns that uniquely identify a row in the table. For example, an employee number uniquely identifies an employee—emp_id is the primary key of the employee table.

The sales_order_items table is an example of a table with two columns that make up the primary key. The order ID by itself does not uniquely identify a row in the sales_order_items table because there can be several items in an order. Also, the line_id number does not uniquely identify a row in the sales_order_items table. Both the order ID name and line_id are required to uniquely identify a row in the sales_order_items table. The primary key of the table is both columns taken together.


Tables are related by a foreign key
User's Guide

PART 2. Tutorials

CHAPTER 8. Joining Tables

How tables are related

Tables are related by a foreign key

There are several tables in the employee database that refer to other tables in the database. For example, the sales_order table has a sales_rep column to indicate which employee is responsible for an order. Only enough information to uniquely identify an employee is kept in the sales_order table. The sales_rep column in the sales_order table is a foreign key to the employee table.

Foreign key

A foreign key is one or more columns that contain primary key values from another table. Each foreign key relationship in the employee database is represented by an arrow between two tables. The arrow starts at the foreign key side of the relationship and points to the primary key side of the relationship.


Join operators
User's Guide

PART 2. Tutorials

CHAPTER 8. Joining Tables

Join operators

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 example you have already seen restricts foreign key values in the sales_order table to be equal to the primary key values in the employee table.

SELECT emp_lname, id, order_date

FROM sales_order, employee

WHERE sales_order.sales_rep = employee.emp_id

The query can be more simply expressed using a KEY JOIN.

 Joining tables using key joins

 Joining tables using natural joins


Joining tables using key joins
User's Guide

PART 2. Tutorials

CHAPTER 8. Joining Tables

Join operators

Joining tables using key joins

Key joins are an easy way to join tables related by a foreign key. For example:

SELECT emp_lname, id, order_date

FROM sales_order

KEY JOIN employee

gives the same results as a query with a WHERE clause that equates the two employee number columns:

SELECT emp_lname, id, order_date

FROM sales_order, employee

WHERE sales_order.sales_rep = employee.emp_id

The join operator (KEY JOIN) is just a short cut for typing the WHERE clause; the two queries are identical.

If you look at the diagram of the employee database, foreign keys are represented by lines between tables. Anywhere that two tables are joined by a line in the diagram, you can use the KEY JOIN operator.

Joining two or more 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 lines between the tables.

SELECT company_name,

CAST( SUM(sales_order_items.quantity *

product.unit_price) AS INTEGER) AS value

FROM customer

KEY JOIN sales_order

KEY JOIN sales_order_items

KEY JOIN product

GROUP BY company_name

company_name	value
Able Inc.	6120
AMF Corp.	3624
Amo & Sons	3216
Amy's Silk Screening	2028
Avco Ent	1752
...
The CAST function used in this query converts the data type of an expression.


Joining tables using natural joins
User's Guide

PART 2. Tutorials

CHAPTER 8. Joining Tables

Join operators

Joining tables using natural joins

The NATURAL JOIN operator joins two tables based on common column names. In other words, SQL Anywhere generates a WHERE clause that equates the common columns from each table.

Example

For example, for the following query:

SELECT emp_lname, dept_name

FROM employee

NATURAL JOIN department

the database engine looks at the two tables and determines that the only column name they have in common is dept_id. The following WHERE clause is internally generated and used to perform the join:

...

WHERE employee.dept_id = department.dept_id

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.

The database engine internally generates the following WHERE clause:

WHERE 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.

You should be careful not to use join operators blindly. Always remember that the join operator just saves you from typing the WHERE clause for a foreign key or common column names. You should be conscious of the WHERE clause, or you may be creating queries that give results other than what you intend.


Obtaining Aggregate Data
User's Guide

PART 2. Tutorials

CHAPTER 9. Obtaining Aggregate Data

About this chapter

This chapter describes how to construct queries that tell you aggregate information. Examples of aggregate information are:

♦	The total of all values in a column

♦	The number of distinct entries in a column

♦	The average value of entries in a column

 A first look at aggregate functions

 Using aggregate functions to obtain grouped data

 Restricting groups


A first look at aggregate functions
User's Guide

PART 2. Tutorials

CHAPTER 9. Obtaining Aggregate Data

A first look at aggregate functions

Suppose you want to know how many employees there are. The following statement retrieves the number of rows in the employee table:

SELECT count( * )

FROM employee

count( * )

75

The result returned from this query is a table with only one column (with title count( * )) and one row, which contains the number of employees.

The following command is a slightly more complicated aggregate query:

SELECT   count( * ),

min( birth_date ),

max( birth_date )

FROM employee

count( * )	min( birth_date )	max( birth_date )
75	1936-01-02	1973-01-18
The result set from this query has three columns and only one row. The three columns contain the number of employees, the birthdate of the oldest employee, and the birthdate of the youngest employee.

COUNT, MIN and MAX are called aggregate functions. Each of these functions summarizes information for an entire table. In total, there are six aggregate functions: MIN, MAX, COUNT, AVG, SUM, and LIST. All but COUNT have the name of a column as a parameter. As you have seen, COUNT has an asterisk as its parameter.


Using aggregate functions to obtain grouped data
User's Guide

PART 2. Tutorials

CHAPTER 9. Obtaining Aggregate Data

Using aggregate functions to obtain grouped data

In addition to providing information about an entire table, aggregate functions can be used on groups of rows.

 To list the number of orders each sales representative is responsible for:

1	Type the following:

SELECT sales_rep, count( * )

FROM sales_order

GROUP BY sales_rep

sales_rep	count( * )
129	57
195	50
299	114
467	56
667	54
The results of this query consist of one row for each sales rep ID number, containing the sales rep ID, and the number of rows in the sales_order table with that number.

Whenever GROUP BY is used, the resulting table has one row for each different value found in the GROUP BY column or columns.

A common error with GROUP BY

A common error with groups is to try to get information which cannot properly be put in a group. For example,

SELECT sales_rep, emp_lname, count( * )

FROM sales_order

KEY JOIN employee

GROUP BY sales_rep

gives the error

column 'emp_lname' cannot be used unless it is in a GROUP BY.

SQL does not realize that each of the rows for an employee with a given ID have the same value of emp_lname. An error is reported since SQL does not know which of the names to display.

However, the following is valid:

SELECT sales_rep, max( emp_lname ), count( * )

FROM sales_order

KEY JOIN employee

GROUP BY sales_rep

The max function chooses the maximum (last alphabetically) surname from the detail rows for each group. The surname is the same on every detail row within a group so the max is just a trick to bypass a limitation of SQL.


Restricting groups
User's Guide

PART 2. Tutorials

CHAPTER 9. Obtaining Aggregate Data

Restricting groups

You have already seen how to restrict rows in a query using the WHERE clause. You can restrict GROUP BY clauses by using the HAVING keyword.

 To list all sales reps with more than 55 orders:

1	Type the following:

SELECT sales_rep, count( * )

FROM  sales_order

KEY JOIN employee

GROUP BY sales_rep

HAVING count( * ) > 55

sales_rep	count( * )
129	57
299	114
467	56
1142	57
Order of clauses—GROUP BY must always appear before HAVING. In the same manner, WHERE must appear before GROUP BY.

HAVING clauses and WHERE clauses can be combined. When combining these clauses, the efficiency of the query can depend on whether criteria are placed in the HAVING clause or in the WHERE clause. Criteria in the HAVING clause restrict the rows of the result only after the groups have been constructed. Criteria in the WHERE clause are evaluated before the groups are constructed, and save time.

 To list all sales reps with more than 55 orders and an ID of more than 1000:

1	Type the following:

SELECT sales_rep, count( * )

FROM sales_order

KEY JOIN employee

WHERE sales_rep > 1000

GROUP BY sales_rep

HAVING count( * ) > 55

The following statement produces the same results.

 To list all sales reps with more than 55 orders and an ID of more than 1000:

1	Type the following:

SELECT sales_rep, count( * )

FROM sales_order

KEY JOIN employee

GROUP BY sales_rep

HAVING count( * ) > 55

AND sales_rep > 1000

The first statement is faster because it can eliminate making up groups for some of the employees. The second statement builds a group for each sales rep and then eliminates the groups with wrong employee numbers. For example, in the first statement, the database engine would not have to make up a group for the sales rep with employee ID 129. In the second command, the database engine would make up a group for employee 129 and eliminate that group with the HAVING clause.

Fortunately, SQL Anywhere detects this particular problem and changes the second query to be the same as the first. SQL Anywhere performs this optimization with simple conditions (nothing involving OR or IN). For this reason, when constructing queries with both a WHERE clause and a HAVING clause, you should be careful to put as many of the conditions as possible in the WHERE clause.


Updating the Database
User's Guide

PART 2. Tutorials

CHAPTER 10. Updating the Database

About this chapter

This chapter describes how to make changes in the contents of a 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 back out of changes you have made.

 Adding rows to a table

 Modifying rows in a table

 Canceling changes

 Making changes permanent

 Deleting rows

 Validity checking


Adding rows to a table
User's Guide

PART 2. Tutorials

CHAPTER 10. Updating the Database

Adding rows to a table

Suppose that a new eastern sales department is created, with the same manager as the current Sales department. You can add this information to the database using the following INSERT statement:

INSERT

INTO department ( dept_id, dept_name, dept_head_id )

VALUES ( 220, 'Eastern Sales', 902 )

If you make a mistake and forget to specify one of the columns, SQL Anywhere reports an error.

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.

A short form for INSERT

There is a short form that can be used if you are entering values for all the columns in a table in the order they appear when you SELECT * from the table (the same as the order in which they were created). The following is equivalent to the previous INSERT command:

INSERT

INTO department

VALUES ( 220, 'Eastern Sales', 902 )

 CautionYou should use this form of INSERT with caution; it will not work as expected if you ever change the order of the columns in the table or if you add or remove a column from the table.


Modifying rows in a table
User's Guide

PART 2. Tutorials

CHAPTER 10. Updating the Database

Modifying rows in a table

In most databases, you need to update data stored in the database. For example, suppose that the employee named James Klobucher (employee ID 467) is transferred from the sales department to the marketing department. In SQL, this is done using the UPDATE statement:

UPDATE employee

SET dept_id = 400

WHERE emp_id = 467

The WHERE clause identifies which employee to update.

Example: using the WHERE clause

SQL can update more than one column at a time. For example, the manager ID should change when employees are transferred between departments, as well as the department ID. The following statement carries out both updates at the same time for employee Marc Dill (employee ID 195):

UPDATE employee

SET dept_id = 400,

manager_id = 1576

WHERE emp_id = 195

The UPDATE and INSERT commands

The UPDATE and INSERT commands are two of the few places in SQL Anywhere where uppercase letters and lowercase letters are distinguished. New character values set by the UPDATE command are stored in the database exactly as they are entered.

SQL allows more than one row to be 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.

It is also possible that an UPDATE statement updates no rows. For example, suppose you had made a mistake typing the employee ID in the first UPDATE statement above:

UPDATE employee

SET dept_id = 400

WHERE emp_id = 194

No rows would be updated since there is no employee with the employee ID 194.


Canceling changes
User's Guide

PART 2. Tutorials

CHAPTER 10. Updating the Database

Canceling changes

You may be a little concerned about all of the changes you have made to the employee table. However, SQL allows you to undo all of these changes with one command:

ROLLBACK

The ROLLBACK statement

The ROLLBACK statement undoes all changes you have made to the database since the last time you made changes permanent (see COMMIT in the next section).

The default action in ISQL is to do a COMMIT on exit. This can be controlled with the ISQL option COMMIT_ON_EXIT.

For more information on ISQL options, see "SET OPTION statement".


Making changes permanent
User's Guide

PART 2. Tutorials

CHAPTER 10. Updating the Database

Making changes permanent

The SQL statement

COMMIT

makes all changes permanent.

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.

Making changes permanent in ISQL

The default action in ISQL is to do a COMMIT on exit. This can be controlled with the ISQL option COMMIT_ON_EXIT.

For more information on ISQL options, see "SET OPTION statement".

ISQL has another option, named AUTO_COMMIT. If this option is on, ISQL does a COMMIT operation after every command. The default for this option is OFF. Usually you will want it OFF, giving you the opportunity to ROLLBACK the changes (if, for example, an update or delete operation doesn't produce the intended results).


Deleting rows
User's Guide

PART 2. Tutorials

CHAPTER 10. Updating the Database

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

Example: using the DELETE command

You can delete more than one row with one command. For example, the following statement would delete all employees who had a termination date that is not NULL from the employee table.

DELETE

FROM employee

WHERE termination_date IS NOT NULL

This example would not remove any employees from the database as the termination_date column is NULL for all employees.

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 employees in the 617 area code with employee ID 902 as manager. This WHERE clause is a compound search condition including a function (LEFT).

DELETE

FROM employee

WHERE LEFT( phone, 3 ) = '617'

AND manager_id = 902

Since you have made changes to the database that you do not want to keep, you should undo the changes as follows:

ROLLBACK


Validity checking
User's Guide

PART 2. Tutorials

CHAPTER 10. Updating the Database

Validity checking

SQL Anywhere automatically checks for some common errors in your data.

 Inserting duplicate data

 Inserting incorrect values

 Errors on DELETE or UPDATE


Inserting duplicate data
User's Guide

PART 2. Tutorials

CHAPTER 10. Updating the Database

Validity checking

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.

Primary key

A primary key is a set of columns that uniquely identifies each row in a table. For example, the dept_id column is the primary key for the department table; given a valid department ID number, there is exactly one row in the department table with that number. The primary key for the sales_order_items table is composed of the id and line_id columns, meaning that there should never be two items in the same order with the same line number.


Inserting incorrect values
User's Guide

PART 2. Tutorials

CHAPTER 10. Updating the Database

Validity checking

Inserting incorrect values

Another mistake is to type an incorrect value. 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 )

Foreign key

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 for foreign key 'ky_so_employee_id' in table 'sales_order'

There is no 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.


Errors on DELETE or UPDATE
User's Guide

PART 2. Tutorials

CHAPTER 10. Updating the Database

Validity checking

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.

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 will be undone. If you have not done a COMMIT, then all changes since you started ISQL will be undone.

Example: UPDATE errors

The same error message is generated if you perform an update operation that makes the database inconsistent.

For example, the following UPDATE statement causes an integrity error:

UPDATE department

SET dept_id = 600

WHERE dept_id = 100

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.

Example: checking the integrity after the COMMIT WORK is complete

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, changing the R&D department's ID from 100 to 600 in the department and employee tables. In order to make these changes, the database has to be inconsistent in between the changes. In this case, you must configure the database to check only on commits.

For information on the WAIT_FOR_COMMIT database option, see "SET OPTION statement".

You can also define foreign keys in such a way that they are automatically fixed. In the above 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.

In the above cases, there is no way to have an inconsistent database committed as permanent. SQL Anywhere also supports alternative actions if changes would render the database inconsistent.

For more information, see the chapter "Ensuring Data Integrity".


Introduction to Views
User's Guide

PART 2. Tutorials

CHAPTER 11. Introduction to Views

About this chapter

It is often impractical to repeatedly type complicated queries. SQL provides views, that allow you to give names to frequently executed SELECT commands. A view is a computed table which is useful for security purposes, and for tailoring the appearance of database information to make data access straightforward.

This chapter introduces you to views.

 Defining a view

 Using views for security


Defining a view
User's Guide

PART 2. Tutorials

CHAPTER 11. Introduction to Views

Defining a view

Suppose that you frequently need to list a summary of employees and the departments they belong to. The following query produces the information you need.

 To list employees and the departments to which they belong:

1	Type the following:

SELECT emp_fname, emp_lname, dept_name

FROM employee JOIN department

ON department.dept_id = employee.dept_id

emp_fname	emp_lname	department
Fran	Whitney	R&D
Matthew	Cobb	R&D
Robert	Breault	R&D
Natasha	Shishov	R&D
Kurt	Driscoll	R&D
You can create a view that produces the results of this command as follows:

CREATE VIEW emp_dept AS

SELECT emp_fname, emp_lname, dept_name

FROM employee JOIN department

ON department.dept_id = employee.dept_id

This command creates a view called emp_dept that looks in many respects just like any other table in the database.

You can list everything in this view just as you do from a table:

 To list employees and the departments to which they belong:

1	Type the following:

SELECT *

FROM emp_dept

emp_fname	emp_lname	department
Fran	Whitney	R&D
Matthew	Cobb	R&D
Robert	Breault	R&D
Natasha	Shishov	R&D
Kurt	Driscoll	R&D
It is important to remember that the information in a view is not stored separately in the database. Each time you refer to the view, SQL executes the associated SELECT statement to find the appropriate data.

On one hand, this is good; it means that if someone modifies the employee table or the department table, the information in the emp_dept view will be automatically up to date. On the other hand, if the SELECT command is complicated it may take a long time for SQL to find the correct information every time you use the view.

Providing names for the view columns

You can provide names for the view columns explicitly. First you must get rid of the original view definition as follows:

DROP VIEW emp_dept

You can redefine the view with the new column name as follows:

CREATE VIEW emp_dept(FirstName, LastName, Department) AS

SELECT emp_fname, emp_lname, dept_name

FROM employee JOIN department

ON department.dept_id = employee.dept_id

You have changed the names of the columns in the view by specifying new column names in parentheses after the view name.

More about views

Views can be thought of as computed tables. Any SELECT command can be used in a view definition except commands containing ORDER BY. Views can use GROUP BY clauses, subqueries, and joins. Disallowing ORDER BY is consistent with the fact that rows of a table in a relational database are not stored in any particular order. When you use the view, you can specify an ORDER BY.

You can also use views in more complicated queries. Here is an example using a join:

SELECT LastName, dept_head_id

FROM emp_dept, department

WHERE emp_dept.Department = department.dept_name


Using views for security
User's Guide

PART 2. Tutorials

CHAPTER 11. Introduction to Views

Using views for security

Example

Views can be used to restrict access to information in the database. For example, suppose you wanted to create a user ID for the sales department head, Moira Kelly, and restrict her user ID so that it can only examine information about employees in the sales department.

Creating the new user ID

First you need to create the new user ID for Moira Kelly using the GRANT statement. From ISQL, connected to the sample database as dba, enter the following:

GRANT CONNECT TO M_Kelly

IDENTIFIED BY SalesHead

Granting permissions

Next you need to grant user M_Kelly the right to look at employees of the sales department.

CREATE VIEW SalesEmployee AS

SELECT emp_id, emp_lname, emp_fname

FROM "dba".employee

WHERE dept_id = 200

The table should be identified as "dba".employee for the M_Kelly user ID to be able to use the view.

Now you must give M_Kelly permission to look at the new view by entering:

GRANT SELECT ON SalesEmployee TO M_Kelly

Looking at the view

Connect to the database as M_Kelly and now try looking at the view:

CONNECT USER M_Kelly IDENTIFIED BY SalesHead ;

SELECT * FROM "dba".SalesEmployee

emp_id	emp_lname	emp_fname
129	Chin	Philip
195	Dill	Marc
299	Overbey	Rollin
467	Klobucher	James
641	Powell	Thomas
However, you do not have permission to look directly at the employee and department tables. If you execute the following commands, you will get permission errors.

SELECT * FROM "dba".employee ;

SELECT * FROM "dba".department


Introduction to Subqueries
User's Guide

PART 2. Tutorials

CHAPTER 12. Introduction to 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.

 Preparing to use subqueries

 A simple subquery

 Comparisons using subqueries

 Using subqueries instead of joins


Preparing to use subqueries
User's Guide

PART 2. Tutorials

CHAPTER 12. Introduction to Subqueries

Preparing to use subqueries

Sometimes it is useful to use the results of one statement as part of another statement.

Example 1

For example, suppose that you need a list of order items for products that are low in stock.

You can look up the products for which there are less than 20 items in stock in the product table.

 To list all products for which there are less than 20 items in stock:

1	Type the following:

SELECT id, description, quantity

FROM product

WHERE quantity < 20

id	description	quantity
401	Wool cap	12
This query shows that only wool caps are low in stock.

Example 2

You can list all the order items for wool caps with the following query:

 To list all orders for wool caps, most recent first:

1	Type the following:

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	1994-07-09
2053	1	401	60	1994-06-30
2125	2	401	36	1994-06-28
2027	1	401	12	1994-06-17
2062	1	401	36	1994-06-17
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.


A simple subquery
User's Guide

PART 2. Tutorials

CHAPTER 12. Introduction to Subqueries

A simple subquery

SQL provides another way to find orders for items low in stock. The following query incorporates a subquery.

Example 1

 To list order items for products low in stock:

1	Type the following:

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	1994-07-09
2053	1	401	60	1994-06-30
2125	2	401	36	1994-06-28
2027	1	401	12	1994-06-17
2062	1	401	36	1994-06-17
By using a subquery, the search can be carried out in just one query, instead of using one query to find the list of low-stock products and a second to find orders for those products.

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.

Example 2

Consider what would happen if an order for ten tank tops were shipped so that the quantity column for tank tops contained the value 18. The query using the subquery, would list all orders for both wool caps and tank tops. On the other hand, the first statement you used would have to be changed to the following:

SELECT *

FROM sales_order_items

WHERE prod_id IN ( 401, 300 )

ORDER BY ship_date DESC

The command using the subquery is an improvement because it still works even if data in the database is changed.

Example 3

As another example, you can list orders for everything except those products in short supply with the query:

SELECT *

FROM sales_order_items

WHERE prod_id NOT IN

(  SELECT id

FROM product

WHERE quantity < 20 )

ORDER BY ship_date DESC


Comparisons using subqueries
User's Guide

PART 2. Tutorials

CHAPTER 12. Introduction to Subqueries

Comparisons using subqueries

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 contents of the fin_code table:

1	Type the following:

SELECT *

FROM fin_code

code	type	description
e1	expense	Fees
e2	expense	Services
e3	expense	Sales & Marketing
e4	expense	R&D
e5	expense	Administration
r1	revenue	Fees
r2	revenue	Services
The fin_data table holds financial data for each financial code for each quarter.

 To list the contents of the fin_data table:

1	Type the following:

SELECT *

FROM fin_data

year	quarter	code	amount
1992	Q1	e1	101
1992	Q1	e2	403
1992	Q1	e3	1437
1992	Q1	e4	623
1992	Q1	e5	381
The following query uses a subquery to list just the revenue items from the fin_data table.

 To list the revenue items from the fin_data table:

1	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
1992	Q1	r1	1023
1992	Q2	r1	2033
1992	Q3	r1	2998
1992	Q4	r1	3014
1993	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.

Notes about subqueries

Subqueries are restricted to one column name listed between SELECT and FROM: one select-list item. The following example does not make sense, since SQL would not know which column from fin_code to compare to the fin_data.code column.

SELECT *

FROM fin_data

WHERE fin_data.code IN

(  SELECT fin_code.code, fin_code.type

FROM fin_code

WHERE type = 'revenue' )

Further, while subqueries used with an IN condition may return several rows, a subquery used with a comparison operator must return only one row. For example, the following command will result in an error since the subquery returns two rows (r1, and r2):

SELECT *

FROM fin_data

WHERE fin_data.code =

 (  SELECT fin_code.code

FROM fin_code

WHERE type = 'revenue' )

The IN comparison allows several rows. 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 * s

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 word ALL 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' )


Using subqueries instead of joins
User's Guide

PART 2. Tutorials

CHAPTER 12. Introduction to Subqueries

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 1994:

1	Type the following:

SELECT     sales_order.id,

sales_order.order_date,

customer.company_name

FROM sales_order

KEY JOIN customer

WHERE order_date > '1994/01/01'

ORDER BY order_date

id	order_date	company_name
2473	1994-01-04	Peachtree Active Wear
2474	1994-01-04	Sampson & Sons
2036	1994-01-05	Hermanns
2106	1994-01-05	Salt & Pepper's
2475	1994-01-05	Cinnamon Rainbow's
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 > '1994/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:

1	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	MAX(id)	state
Custom Designs	2547	WA
It's a Hit!	(NULL)	WA
The It's a Hit! company placed no orders, and the subquery returns NULL for this customer. Companies who have not placed an order would not be listed if an inner join was used.

You could also specify an outer join explicitly. In this case a GROUP BY clause is also required.

SELECT  company_name,

MAX( sales_order.id ),state

FROM customer

KEY LEFT OUTER JOIN sales_order

WHERE state = 'WA'

GROUP BY company_name, state


Command Files
User's Guide

PART 2. Tutorials

CHAPTER 13. Command Files

About this chapter

This chapter describes how to use the ISQL command window to enter multiple commands at a time and to process files consisting of a set of commands.

 Entering multiple statements in the ISQL Command window

 Saving statements as command files

 Command files with parameters


Entering multiple statements in the ISQL Command window
User's Guide

PART 2. Tutorials

CHAPTER 13. Command Files

Entering multiple statements in the ISQL Command window

SQL commands can get quite large. You have already seen how to use the editor to enter commands on several lines. The ISQL environment also allows multiple commands to be entered at the same time. This is done by ending each command with a semi-colon (;).

You may want to grow the Command window:

♦	In DOS, OS/2 or QNX, choose Command [image] Zoom from the menu bar.

♦	In Windows or Windows NT, click the maximize button.

Example: entering multiple statements

 To enter multiple statement in the ISQL Command Window

1	Try entering the following three commands into the Command window.

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	Press the execute key (F9). All three of these commands are executed. After execution, the commands are left in the Command window.

You can modify the commands if there are errors.


Saving statements as command files
User's Guide

PART 2. Tutorials

CHAPTER 13. Command Files

Saving statements as command files

You can also save the commands entered in the previous section to a command file. This keeps a permanent record of the SQL commands so they can be used later if you wish.

 To save statements as a command file:

1	Choose File [image] Save As from the menu bar. You are then prompted for a filename.

2	Type transfer and press ENTER.

3	The command file can be run using the ISQL READ command, but you should rollback the changes first. Press the ESCAPE key to clear the editor and then execute the ROLLBACK WORK command.

4	Now enter the following command:

READ transfer

This command executes the command file transfer which contains the three commands that we saved previously. As each command is executed, it flashes up in the Command window.

5	You can load command files back into the Command window by choosing File [image] Open from the menubar.

6	Enter transfer when prompted for the file name. Notice that the commands have been loaded back into the editor just the way they were when they were saved.

What are command files?

Command files are just ASCII files containing the ISQL commands as you see them in the editor. You can use any editor you like to create command files. You can include comment lines along with the SQL statements to be executed. Comments begin with a percent sign (%). The ISQL READ command is used to execute command files. Alternatively, they can be loaded into the ISQL Command window and executed directly from there.

The Command window in ISQL has a limit of 500 lines. For command files larger than this, you should use a generic editor capable of handling large files. The READ command has no limit on the number of lines that can be read.


Command files with parameters
User's Guide

PART 2. Tutorials

CHAPTER 13. Command Files

Command files with parameters

An example of a command file that would take a parameter is a command file to show the department an employee belongs to, providing the employee's name as a parameter.

 To create a command file with parameters:

1	Create a command file as listed below.

The PARAMETERS command is used to give names to the parameters passed to a command file. In this case, we are giving the first parameter the name employee_name. The parameters are then used in the rest of the command file by enclosing them in braces ({}). Save the command file to emp_dept.sql.

% This command file has one parameter

parameters employee_name;

select emp_lname, dept_name

from  employee

NATURAL JOIN department

where emp_lname = {employee_name};

2	Run this command file by typing:

READ emp_dept.sql

3	You will be prompted for the employee_name. Enter the following value, including the single quotes:

'Whitney'

You should now see that the employee with surname Whitney is in the R&D department.

Parameters specifies on the READ command

Parameters can also be specified on the READ command. Try the following command:

READ emp_dept.sql 'whitney'

In this case you have specified the parameter on the READ command, so ISQL will not prompt for it. ISQL will only prompt for parameters that are named in the PARAMETERS command but are not supplied on the READ command.


System Tables
User's Guide

PART 2. Tutorials

CHAPTER 14. System Tables

About this chapter

This chapter describes the system tables, several special tables found in every SQL Anywhere database. These system tables describe all the tables and columns in the database. The SQL Anywhere software automatically updates the system table as the database structure is changed.

This chapter introduces the system tables.

 The SYSCATALOG table

 The SYSCOLUMNS table

 Other system tables


The SYSCATALOG table
User's Guide

PART 2. Tutorials

CHAPTER 14. System Tables

The SYSCATALOG table

The first system table lists all the tables in the database.

 To view the contents of the SYSCATALOG table for the sample database:

1	Type the following command:

SELECT *

FROM sys.syscatalog

The first screen of tables lists some of the system tables found in SQL Anywhere.

2	Scroll through the ISQL data window a few times, you will see the tables that make up the company database.

The creator of the system table

The creator of the system tables is the special user ID, SYS and the creator of the company tables is dba. In addition, there is a set of views owned by the special user ID DBO, which provide an emulation of the Sybase SQL Server system catalog; these tables are not discussed in this section.

(Recall that dba is the user ID you used when connecting to the database from ISQL.) So far, you have simply typed the table names employee and department; SQL looked in SYSCATALOG for tables with those names created by dba. In this example, by typing SYS.SYSCATALOG you specified that SYSCATALOG was created by the user ID SYS. Note the similarity to the way column names are qualified, such as employee.emp_id.

Other columns in the system table

The other columns in this table contain other important information. For example, the column named Ncols is the number of columns in each table, and the column named tabletype identifies the table as a permanent table (also called a base table) or a view.


The SYSCOLUMNS table
User's Guide

PART 2. Tutorials

CHAPTER 14. System Tables

The SYSCOLUMNS table

Another important system table is called SYSCOLUMNS describing all the columns in all the tables in the database. To see the contents of this table, type the command:

SELECT *

FROM sys.syscolumns

WHERE tname = 'employee'

This command lists all the columns in the employee table. If you look at the columns to the right, you can see from the Coltype column that some columns in the employee table contain character information; others contain integer and date information.


Other system tables
User's Guide

PART 2. Tutorials

CHAPTER 14. System Tables

Other system tables

There are several other system tables in the database that will not be described in the tutorial. You can find out their names by examining SYS.SYSCATALOG and look at them if you want.

For a full description of each of the system tables, see the chapter "SQL Anywhere System Tables".


Using SQL Anywhere
User's Guide

PART 3. Using SQL Anywhere

This part describes how to use the SQL Anywhere database management system.

 CHAPTER 15. Connecting to a Database

 CHAPTER 16. Designing Your Database

 CHAPTER 17. Working with Database Objects

 CHAPTER 18. Ensuring Data Integrity

 CHAPTER 19. Using Transactions and Locks

 CHAPTER 20. Using Procedures, Triggers, and Batches

 CHAPTER 21. Monitoring and Improving Performance

 CHAPTER 22. Database Collations

 CHAPTER 23. Importing and Exporting Data

 CHAPTER 24. Managing User IDs and Permissions

 CHAPTER 25. Backup and Data Recovery

 CHAPTER 26. Introduction to SQL Remote Replication

 CHAPTER 27. SQL Remote Administration

 CHAPTER 28. Running Programs as Services


Connecting to a Database
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 15. Connecting to a Database

About this chapter

This chapter describes how client applications connect to SQL Anywhere databases and contains all the SQL Anywhere-specific information about connecting to databases from ODBC-enabled applications and application development systems.

If you are writing a program directly using one of the programming interfaces to SQL Anywhere, see "Programming Interfaces" for implementation details.

 Connection overview

 Connecting from the SQL Anywhere utilities

 Connecting from an ODBC-enabled application


Connection overview
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 15. Connecting to a Database

Connection overview

Any client application that uses a database must establish a connection to that database before any work can be done. While the user may be prompted to enter a user ID, a password, and other parameters, the connection is established by the client application through one of SQL Anywhere's programming interfaces.

Once the connection is established, it forms the channel through which all the activity you engage in from the client application takes place. For example, the permissions you have to carry out actions on the database are determined by your user ID—and the database engine is aware of your user ID because it is part of the request to establish a connection.

 Database connection parameters

 Connection keyword meanings

 How client applications connect to a database


Database connection parameters
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 15. Connecting to a Database

Connection overview

Database connection parameters

When an application connects to a database, it uses a set of connection parameters, collected together in a connection string, to define the connection. For example, connection strings specify a user ID and password, as well as other optional information; all connections using  ODBC must supply a Data Source name.

Connection parameters used with SQL Anywhere databases

A large class of client applications uses a very similar set of connection parameters when attempting to connect to a SQL Anywhere database. These are:

♦	All applications connecting to SQL Anywhere databases through the ODBC interface using the SQLDriverConnect function. This includes many ODBC-enabled application development systems, as well as applications developed using those systems.

♦	The SQL Anywhere database utilities ISQL, DBBACKUP, DBWATCH, DBUNLOAD, and DBVALID.

♦	All other embedded SQL applications connecting using the db_string_connect function, which is the recommended way to connect to a database in embedded SQL.

Methods used to specify connection parameters

The way you specify the connection parameters depends on the particular client application you are working from. Applications may use one of the following methods:

♦	ODBC-enabled applications use a Data Source configuration, which may be entered using the ODBC Administrator program

  For more information on adding an ODBC data source using the ODBC Administrator, see "Adding an ODBC data source".

♦	You may be prompted to fill in fields in a dialog box

♦	You may be required to enter command-line arguments

♦	The application may look in prespecified files to find the parameter values

♦	The application may use environment variable settings

♦	The application may have a fixed set of parameters built in permanently

Keywords used in connection strings

All these applications use a connection string consisting of a list of parameter settings, each of the form keyword=value, delimited by semicolons. The keywords must come from the following table.

Verbose keyword	Short form	Argument
Agent	Agent	string (Client or Engine)
AutoStop	AutoStop	YES/NO
ConnectionName *	CON	string
DatabaseFile	DBF	string
DatabaseName	DBN	string
DatabaseSwitches	DBS	string
DatasourceName #**	DSN	string
EngineName	ENG	string
Password **	PWD	string
Start	Start	string
Userid **	UID	string
* Not supported in ODBC connections

# Supported in ODBC connections only

** Verbose form of keyword not supported in ODBC connection parameters

For more information on connection parameters, see "Connection keyword meanings", next

  For information on other ODBC-specific connection parameters, see "Adding an ODBC data source".


Connection keyword meanings
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 15. Connecting to a Database

Connection overview

Connection keyword meanings

The meaning of each of the connection parameter keywords is as follows:

Keyword	Description
Agent	If you have both a standalone engine and a client available, and you wish to ensure that you correct to one of these, you can specify Agent=client or Agent=engine to ensure a connection to the appropriate agent..
AutoStop	You should supply an AutoStop keyword only if you are connecting to a database that is not currently running. If AutoStop is set to yes then the database is unloaded automatically as soon as there are no more open connections to it.
ConnectionName	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. ConnectionName is not used when connecting through ODBC
DatabaseFile	The root file of the database to which you want to connect You should supply a DatabaseFile only if you are connecting to a database that is not currently running. For example, to start and connect to the sample database (installed in directory c:\sqlany50), use a DatabaseFile entry of c:\sqlany50\sademo.db.
DatabaseName	When a database is started, it is assigned a database name. The default database name is the name of the database file with the extension and path removed.   For more information about the database name see "Some database terms".   For information on this field, see "How client applications connect to a database"
DatabaseSwitches	You should supply DatabaseSwitches only if you are connecting to a database that is not currently running. When the engine starts the database specified by DatabaseFile, the engine uses the supplied DatabaseSwitches as command line options to determine startup options for the database. Only database switches can be supplied using this keyword. Engien or server switches must be supplied using the START connection parameter.    For more information about database switches, see "The database engine".
DataSourceName	The DataSourceName tells an  ODBC application where to look in  ODBC.INI to find information about the database to which you want to connect. DataSourceName is used only by ODBC-enabled applications, and is compulsory for this class of application
EngineName	The name of a running database engine or server to which you want to connect. You need to supply a server name only if more than one database engine is running.   For more information about the engine name see "Some database terms". In the Sybase Central and ISQL Connect dialog box, and in the ODBC Administrator, this is the Server Name field
Password	Your database password. You must always supply a password when connecting to a database
Start	You should supply a Start keyword only if you are connecting to a database engine that is not currently running. The Start parameter is a command line to start a database engine.   For a detailed description of available command line switches, see "The database engine".
Userid	The user ID with which you log on to the database. You must always supply a user id when connecting to a database
For a detailed description of how client applications use the connection parameters when connecting to a database, see "How client applications connect to a database".


How client applications connect to a database
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 15. Connecting to a Database

Connection overview

How client applications connect to a database

Once you have specified the connection parameters, using whatever method your client application requires, the application attempts to connect to a database. The procedure the client follows is exactly the same for each of two important sets of client application:

♦	Any ODBC-enabled client application. Many application development systems, such as Powersoft PowerBuilder, belong to this class of application.

♦	Any client application using embedded SQL and using the recommended function for connecting to a database (db_string_connect). All the SQL Anywhere database tools, including ISQL, are a part of this set.

Connecting to a database

Connecting to a database is of fundamental importance: you cannot do any work on a database without first connecting to it. For this reason, the process followed by client applications is described in detail:

♦	The application tries to find the appropriate database engine or server.

♦	If EngineName is specified, the application looks for a local database engine with that name, and then for a SQL Anywhere Client (DBCLIENT) with that server name. For QNX, the application looks on the network for an engine or server.

♦	If EngineName is not specified, the application tries to connect to the default local engine. (If there is only one engine running, it is the default, otherwise the default choice is operating-system specific.)

♦	If no matching local database engine is found, and the SQL Anywhere Client is not running, the application starts a database engine or SQL Anywhere Client using the Start parameter.

♦	If no Start parameter is specified, but DatabaseFile is specified, the application attempts to start a database engine on the named file, using a default start parameter.

♦	For more information about database engine parameters, see "The database engine".

♦	If the application successfully finds or starts a database, the application tries to connect to the database. (If no engine has yet been found or started, the attempt to connect fails at this point)

♦	If neither a DatabaseName nor a DatabaseFile is given, the application attempts to connect to the default database on the engine, using the specified Userid, Password, and ConnectionName parameters.

♦	If the database named by DatabaseName is running, the application attempts to connect to the database using the specified Userid, Password, and ConnectionName parameters.

♦	If DatabaseName is not specified, but DatabaseFile is, the application attempts to connect to a database whose name is the root of DatabaseFile.

♦	If no running database is found, but a database specified by the root of DatabaseFile is running, the application attempts to connect to the database using the specified Userid, Password, and ConnectionName parameters.

♦	If the database corresponding to DatabaseFile is not running, the application sends a request to the engine or network server to start a database using the DatabaseFile, DatabaseName, and DatabaseSwitches parameters. (The AutoStop parameter determines if the database automatically stops when the last connection to the database is disconnected.) The application then attempts to connect to the database using the specified Userid, Password, and ConnectionName parameters.

♦	If no connection is made, the attempt fails at this point.

CONNECT statement from ISQL—The ISQL 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 engine is specified in the CONNECT statement, ISQL connects to the current database, rather than to the default database. This behavior is required for database reloading operations.
   For an example, see "CONNECT statement".


Connecting from the SQL Anywhere utilities
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 15. Connecting to a Database

Connecting from the SQL Anywhere utilities

All SQL Anywhere database utilities that communicate with the database engine (rather than acting directly on database files) do so using embedded SQL, and follow the procedure outlined in "How client applications connect to a database" when connecting to a database.

How database tools obtain connection parameter values

Many of the database tools obtain the values of the connection parameters in the following way:

♦	If there are values specified on the command line, those values are used for the connection parameters. For example, the following command starts a backup of the default database on the default database engine using the user ID DBA and the password SQL:

DBBACKUP -c "UID=DBA;PWD=SQL" c:\backup

♦	If any  line values are missing, the application looks at the setting of the SQLCONNECT environment variable. This variable is not set automatically by SQL Anywhere. If you use a single set of connection parameters frequently, you may want to place a SQLCONNECT environment variable in your AUTOEXEC.BAT file (under DOS and Windows 3.x), your CONFIG.SYS file (under OS/2), the Control Panel (under NT) or the login file (under QNX).

  For a description of the SQLCONNECT environment variable, see "Registry entries and environment variables".

♦	If parameters are not set in the command line (if applicable), or the SQLCONNECT environment variable, then by the connection procedure described above, the application prompts for a user ID and password to connect to the default database on the default database engine

For a description of command line switches for each database tool, see chapter "SQL Anywhere Components".


Connecting from an ODBC-enabled application
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 15. Connecting to a Database

Connecting from an ODBC-enabled application

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 the Windows and Windows NT environments. Many client applications, including application development systems, use the ODBC interface to access a wide range of database systems. These are ODBC-enabled applications. SQL Anywhere supports the ODBC interface.

This section describes how to connect to SQL Anywhere from ODBC-enabled applications.

For information about how to write an ODBC program, see the chapter "ODBC Programming".

ODBC-enabled applications use a set of connection parameters in the manner described above. However, they obtain values for those parameters in a different manner to embedded SQL applications. ODBC defines data sources. Each data source description contains several of the required connection parameters. The other connection parameters are obtained from the user (for instance, you may be presented with a dialog box to enter a user ID and password), or internally by the client application.

 SQL Anywhere support for ODBC

 Using ODBC under Windows and Windows NT

 Files needed for ODBC connections

 Working with ODBC data sources

 Using the ODBC Administrator

 Adding an ODBC data source

 Some sample ODBC data sources

 Modifying an existing ODBC data source

 Removing an ODBC data source

 Using ODBC under OS/2

 Using ODBC under DOS and QNX


SQL Anywhere support for ODBC
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 15. Connecting to a Database

Connecting from an ODBC-enabled application

SQL Anywhere support for ODBC

SQL Anywhere provides ODBC Version 2.5 support at conformance Level 2, which is the highest level of support for ODBC Version 2.5.

With Windows and Windows NT

For Windows and Windows NT, SQL Anywhere ODBC support takes place using the Microsoft ODBC driver manager, installed as part of the SQL Anywhere installation. The ODBC driver manager enables different ODBC drivers to run at the same time and allows an ODBC-enabled application to communicate with more than one ODBC driver and data source.

For more information about using ODBC under Windows and Windows NT, see "Using ODBC under Windows and Windows NT".

With DOS and QNX

For DOS and QNX, SQL Anywhere supports  ODBC as an API (application programming interface) only.

For more information about using ODBC under DOS and QNX, see "Using ODBC under DOS and QNX".

With OS/2

SQL Anywhere supports ODBC as an application programming interface for OS/2. Additional software from third party vendors does allow the use of the SQL Anywhere ODBC driver from ODBC-enabled client applications through the third party ODBC driver manager.

For more information about using ODBC client applications under OS/2, see "Using ODBC under OS/2"


Using ODBC under Windows and Windows NT
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 15. Connecting to a Database

Connecting from an ODBC-enabled application

Using ODBC under Windows and Windows NT

All the information about installed ODBC database management systems and databases on your machine is held in two files (in Windows 3.x) or in the registry (in Windows 95 and NT). ODBCINST.INI holds the information about different ODBC DBMS drivers installed on your system, including SQL Anywhere. ODBC.INI holds information about available data sources.

You can look at and alter the information in these files using the ODBC Administrator. The SQL Anywhere installation for Windows operating systems installs the ODBC Administrator as one of the icons in your SQL Anywhere group.


Files needed for ODBC connections
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 15. Connecting to a Database

Connecting from an ODBC-enabled application

Files needed for ODBC connections

The files needed for ODBC client applications to connect to a SQL Anywhere database are as follows for the case of a Windows 95 or NT setup:

Under Windows and Windows NT, ODBC-enabled client applications call the ODBC driver manager. For Windows 3.x, the ODBC driver manager is  ODBC.DLL, installed in your Windows SYSTEM subdirectory; for Windows 95 and NT this is ODBC32.DLL, installed in your NT SYSTEM32 subdirectory or your Windows 95 SYSTEM subdirectory. A third-party driver manager is available from Intersolv, Inc., providing similar functionality for OS/2.

Each ODBC-supporting DBMS, including SQL Anywhere, supplies its own ODBC driver, which is called by the ODBC driver manager. Each ODBC driver is a DLL.

The SQL Anywhere ODBC driver

The SQL Anywhere ODBC driver is installed as part of your SQL Anywhere setup.

♦	For Windows 3.x, this driver is WOD50W.DLL. The SQL Anywhere installation places the WOD50W.DLL file in the WIN subdirectory of your SQL Anywhere installation directory.

♦	For Windows 95 and NT, the driver is WOD50T.DLL. The SQL Anywhere installation places the WOD50T.DLL file in theWIN 32 subdirectory.

♦	For OS/2, the driver is WOD502.DLL. The SQL Anywhere installation places the WOD502.DLL file in the OS2 subdirectory.

The location of the SQL Anywhere ODBC driver is recorded in ODBCINST.INI, which is kept in your Windows directory or in the registry.

Windows and DOS default character set

The default Windows character set differs in some cases from that used by DOS in the default (code page 437). The Windows character set is sometimes called the ANSI character set, and the DOS code page is sometimes called the OEM character set.

A translation DLL can be used to convert characters from the ANSI character set (used by a Windows application) to the default character set in use by the database (code page 437), and vice versa. This translation DLL is:

♦	For Windows 3.x, WTR50W.DLL

♦	For Windows 95 or NT, WTR50T.DLL

♦	For OS/2, WTR502.DLL

OEM to ANSI character set translation

OEM to ANSI character set translation does not affect the alphabetic and numeric characters. It does affect some graphics characters that occupy higher positions in the collation.

Additional files required by the SQL Anywhere ODBC driver

The SQL Anywhere ODBC driver requires additional files. Under Windows, DBL50W.DLL needs to be in the DOS path, under Windows 95 or NT, DBL50T.DLL is required; and under OS/2; DBL502.DLL is required. These files are installed in the Windows, NT, or OS2 subdirectories of your SQL Anywhere installation directory.

A language DLL is also required, as specified in the SQLANY.INI file or registry. For Windows 3.x, SQLANY.INI should be in your Windows directory; for Windows 95 and NT SQLANY.INI is a registry. The SQL Anywhere installation does not install SQLANY.INI; but it is created when you run ISQL or Sybase Central. The default language DLL is WL50EN.DLL (English); other languages must be specified separately.

The ODBCINST.INI file

A file or registry entry named ODBCINST.INI holds information about all the ODBC drivers on the computer. When SQL Anywhere is installed, it adds a description of the SQL Anywhere ODBC driver to ODBCINST.INI, which is held in the Windows 3.x system subdirectory, and in the Windows 95 or NT registry. If you start the ODBC Administrator, and click the Driver button, you should see Sybase SQL Anywhere 5.0 listed among the installed ODBC drivers.

You should not have to make any modifications concerning the SQL Anywhere driver.

SQL Anywhere driver description in Windows 3.x  ODBCINST.INI

The description of the SQL Anywhere driver in the Windows 3.x ODBCINST.INI includes the following:

[ODBC Drivers]

Sybase SQL Anywhere 5.0=Installed

[ODBC Translators]

Sybase SQL Anywhere 5.0 Translator=Installed

[Sybase SQL Anywhere 5.0]

Driver=c:\sqlany50\win\wod50w.dll

Setup=c:\sqlany50\win\wod50w.dll

[Sybase SQL Anywhere 5.0 Translator]

Translator=c:\sqlany50\win\wtr50w.dll

Setup=c:\sqlany50\win\wtr50w.dll

The corresponding information is held in the Windows 95 or NT registry.


Working with ODBC data sources
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 15. Connecting to a Database

Connecting from an ODBC-enabled application

Working with ODBC data sources

For each database that you want to access from an ODBC client application on your computer, you need to enter a Data Source in the  ODBC.INI file or registry. In Windows and Windows NT, you can enter the Data Source description using the ODBC Administrator. The information contained about each Data Source in ODBC.INI includes several of the connection parameters needed to connect to a database.

Some application development systems, such as PowerBuilder, add this information automatically if you create a data source from within the system. In this case you do not need to use the ODBC Administrator.

The SQL Anywhere sample database information is automatically installed into this file during SQL Anywhere setup. You can see the Data Source information for the sample database using the ODBC Administrator.

If you are having trouble connecting to a SQL Anywhere database from an ODBC-enabled client application, check that the information in the Data Source definition is correct.

For more information about using the ODBC Administrator, see "Using the ODBC Administrator".


Using the ODBC Administrator
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 15. Connecting to a Database

Connecting from an ODBC-enabled application

Using the ODBC Administrator

Although you can add, remove and modify data source information by directly editing the ODBC.INI file in Windows or by using the registry editor in Windows NT, it is much easier to use the ODBC Administrator program.

The left side of the Administrator window lists the available data sources including the SQL Anywhere sample database.

If you have other ODBC software installed on your computer, you may have other data sources available. Pressing the Drivers button will display a list of the currently installed ODBC drivers, and allow you to install new ODBC drivers or remove drivers.

The following actions are available for data sources:

♦	"Adding an ODBC data source"

♦	"Modifying an existing ODBC data source"

♦	"Removing an ODBC data source"


Adding an ODBC data source
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 15. Connecting to a Database

Connecting from an ODBC-enabled application

Adding an ODBC data source

The SQL Anywhere ODBC driver can access databases through local SQL Anywhere engines or SQL Anywhere network servers.

Database must exist—To add a data source for a database file, the database must already exist. See "Working with Database Objects" for information on creating a new database. You must create a database before using the ODBC Administrator program to add a data source for the database.

 To add a new data source:

1	If you want to add a new data source, click Add. A list of the available drivers is displayed.

2	Select the SQL Anywhere driver from the list and click OK. The SQL Anywhere ODBC Configuration window is displayed:

The SQL Anywhere ODBC Configuration window contains the following fields, which correspond to connection parameters in a connection string.

  For a description of connection parameters and a description of the manner in which they are used to establish a connection with a database, see "Database connection parameters".

ODBC Configuration dialog box - field descriptions

The following table lists the fields in the SQL Anywhere ODBC Configuration window.

Field	Description
Data Source Name	This should be a short name for the data source, such as Orders or Accounts Payable
Description	A longer description of the data source
User ID	(Optional) The user name to be used when connecting. If the user ID is omitted, most applications prompt you for a user ID and password when connecting to the data source
Password	(Optional) The password for the supplied User ID. Since the password supplied is stored in ODBC.INI, setting the password here may be a security risk. If the password is omitted, most applications prompt you to enter your password when connecting to the data source
Server Name	The name of a SQL Anywhere database engine or server. If not specified, the default engine is used. This field corresponds to the EngineName connection parameter
Database Name	If specified, this corresponds to the name of a database already running on a SQL Anywhere database engine or SQL Anywhere network server. This field corresponds to the DatabaseName connection parameter.
Database File	If specified, this contains the name of a database file—such as C:\sqlany50\sademo.db. You can use the Browse button to locate a database file name to place in this field. This field corresponds to the DatabaseFile connection parameter.
Local, Network, Custom	The command used to run the database software when the named database engine or server is not already executing. You can select Local or Network, as appropriate, if the default settings are satisfactory. Otherwise, select Custom and enter the command including any command line parameters by pressing the Options button
Microsoft Applications (Keys in SQLStatistics)	The ODBC specification states that primary and foreign keys should not be returned by SQLStatistics. Some programs (including Microsoft Visual Basic V3.0 and Microsoft Access V1.0 and V1.1) assume that primary and foreign keys are returned by SQLStatistics. Checking this option makes the SQL Anywhere ODBC driver mimic the required behavior so these applications work properly
Prevent Driver not Capable Errors	The SQL Anywhere ODBC driver returns a "Driver not Capable" error code because it does not support qualifiers. Some ODBC applications do not handle this error properly. Checking this box disables this error code, allowing these applications to work.
Delay AutoCommit until statement close	The ODBC standard specifies that the default mode of operation is to run in auto-commit mode (each statement is committed immediately after it is executed).  Some applications do not provide a way for users to override this behaviour. Checking this option causes the SQL Anywhere ODBC driver to delay the commit operation until the statement is closed.
Windows ODBC.INI

The following example shows the description of the SQL Anywhere sample database and a sample SQL Anywhere client in the Windows  ODBC.INI:

[ODBC Data Sources]

SQL Anywhere 5.0 Sample=Sybase SQL Anywhere 5.0

[SQL Anywhere 5.0 Sample]

driver=c:\sqlany50\win\wod50w.dll

description=Sybase SQL Anywhere Sample Database

DatabaseFile=c:\sqlany50\sademo.db

Start=c:\sqlany50\win\dbeng50w -d

[SQL Anywhere 5.0 Sample Client]

driver=c:\sqlany50\win\wod50w.dll

description=SQL Anywhere Client/Server

EngineName=place_server_name_here

Start=c:\sqlany50\win\dbclienw


Some sample ODBC data sources
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 15. Connecting to a Database

Connecting from an ODBC-enabled application

Some sample ODBC data sources

This section presents some sample SQL Anywhere ODBC data source descriptions.  The descriptions are presented as settings in the SQL Anywhere ODBC Configuration window.

The parameters Description, User ID, and Password are not described here.  The Description parameter is not required, and the User ID and Password can be provided at connection time from the client application.

The examples describe a data source running the sample database (SADEMO.DB), running as a database named sademo on an engine named SampleServer.

Sample data source for connecting to a running engine

The following settings describe an ODBC data source for a standalone database engine running on the local machine. The database is assumed to be running when the application connects; there is no provision in this data source description for starting up a database engine or for loading a database on the engine.

Parameter	Setting
Data Source Name	Sample Name
Server Name	SampleServer
Database Name	sademo
Database File	No entry
Local / Network / Custom option	Local
Translator	No entry
Sample data source for a named database file

The following settings describe an ODBC data source for a named database file.  The description loads the database file on the default local database engine, or connects to a database with the name sademo if it is already running.

Parameter	Setting
Data Source Name	Sample Name
Server Name	No entry
Database Name	No entry
Database File	C:\SQLANY50\SADEMO.DB
Local / Network / Custom option	Local
Translator	No entry
Sample data source for a network server

The following settings describe an ODBC data source for a database running on a network server.  The database is assumed to be running when the application connects; there is no provision in this data source for starting up a database server or for loading a database on the server.

To use this data source you need the SQL Anywhere Client, which is installed with the SQL Anywhere Network Server.

PowerBuilder and InfoMaker users—This chapter contains some information about connecting to a SQL Anywhere network server. The SQL Anywhere network server is not included with PowerBuilder and InfoMaker.

Parameter	Setting
Data Source Name	Sample Name
Server Name	SampleServer
Database Name	sademo
Database File	No entry
Local / Network / Custom option	Network
Translator	No entry


Modifying an existing ODBC data source
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 15. Connecting to a Database

Connecting from an ODBC-enabled application

Modifying an existing ODBC data source

 To modify an existing data source:

1	Select the data source in the ODBC Administrator.

2	Press the Setup button. You can modify any of the attributes set when the data source was added.

For a description of the attributes, see "Adding an ODBC data source".


Removing an ODBC data source
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 15. Connecting to a Database

Connecting from an ODBC-enabled application

Removing an ODBC data source

 To remove an ODBC data source:

1	Select the data source in the ODBC Administrator.

2	Press the Delete button. You are prompted to confirm the deletion.

Database file is not deleted—Removing a data source does not delete the database file. It simply deletes the description of the data source from the ODBC.ini file or Windows NT registry. It can be added back as described above.


Using ODBC under OS/2
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 15. Connecting to a Database

Connecting from an ODBC-enabled application

Using ODBC under OS/2

An ODBC Administrator program and an ODBC driver manager are available for OS/2 and can be acquired from INTERSOLV, Inc. It provides the same functionality as the ODBC Administrator program and  ODBC.DLL driver manager under Windows or Windows NT. The Administrator program is not supplied with SQL Anywhere.

Even if you are not using the ODBC Administrator, the file ODBC.INI is still used to describe the available data sources. Under OS/2,  ODBC.INI is a binary file. As such, it is not easily editable. The SQL Anywhere installation creates this file with a definition of the sample data source. The installation also includes an OS/2 command file, ODBCINI.CMD that uses the REXX API to modify the file. This command file can be modified and run to create additional data sources.


Using ODBC under DOS and QNX
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 15. Connecting to a Database

Connecting from an ODBC-enabled application

Using ODBC under DOS and QNX

The file ODBC.INI is still used to describe the available data sources. This file must be located somewhere in your path. The following example contains a data source definition for the SQL Anywhere sample database:

[ODBC Data Sources]

SQL Anywhere 5.0 Sample=Sybase SQL Anywhere 5.0

[SQL Anywhere 5.0 Sample]

Driver=C:\sqlany50\win\wod50w.dll

Description=Sybase SQL Anywhere Sample Database

DatabaseFile=C:\sqlany50\sademo.db

Start=C:\sqlany50\dos\dbeng50

The first section of the file ([ODBC Data Sources]) lists all of the currently defined data sources. In this case there is only one, called SQL Anywhere 5.0 Sample.

Fields in the second section of SQL Anywhere 5.0 Sample file

The second section of the file ([SQL Anywhere 5.0 Sample]) describes the data source named SQL Anywhere 5.0 Sample. This section contains the following fields:

Fields	Description
Description	A longer description of the data source
UID	(Optional) The user name to be used when connecting. If it is omitted, most ODBC applications will prompt you for a User ID and Password when connecting to the data source
PWD	(Optional) The password for the supplied User ID. Setting the password here may be a security risk because it is easily viewed. If the password is omitted, most applications will prompt you to enter your password when connecting to the data source
DatabaseFile	The name of a SQL Anywhere database file
Start	The command used to run the database software when the named database is not already executing. It contains the command including any command line parameters


Designing Your Database
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 16. Designing Your Database

About this chapter

SQL Anywhere is a relational database management system. This chapter introduces the basic concepts of relational databases and gives you step-by-step suggestions for designing your database.

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. As 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.

This chapter is not specific to SQL Anywhere. If you already have a database, you may wish to go to the next chapter.

This chapter covers database design in a cursory manner. For more information, you may 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.

 Relational database concepts

 Planning the database

 The design process

 Designing the database table properties


Relational database concepts
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 16. Designing Your Database

Relational database concepts

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

 Database tables

 Keys in relational databases

 Each table has a primary key

 Tables are related by foreign keys

 Other database objects


Database tables
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 16. Designing Your Database

Relational database concepts

Database tables

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

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

A typical fragment of 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 database 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

♦	No two rows contain the same set of values

♦	Each value for a given column is of the same type

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

Formal	Informal	Equivalent
relational term	relational term	nonrelational term
Relation	Table	File
Attribute	Column	Field
Tuple	Row	Record


Keys in relational databases
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 16. Designing Your Database

Relational database concepts

Keys in relational databases

Primary and foreign keys enable each row in the database tables to be identified, and enable relationships between the tables to be defined. These keys define the relational structure of a database.


Each table has a primary key
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 16. Designing Your Database

Relational database concepts

Each table has a primary key

Each table in a relational database has a primary key. The primary key is a column, or set of columns, that allows each row in the table to be uniquely identified. No two rows may have the same value of a primary key.

Examples

In a table holding information about employees, the primary key may be an ID number assigned to each employee.

In the sample database, the table of sales order items has the following columns:

♦	An order number, identifying the order the item is part of.

♦	A line number, identifying each item on any order.

♦	A product ID, identifying the product being ordered.

♦	A quantity, showing how many items were ordered.

♦	A ship date, showing when the order was shipped. In order to identify a particular item, both the order number and the line number are required. The primary key is made up of both these columns.


Tables are related by foreign keys
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 16. Designing Your Database

Relational database concepts

Tables are related by foreign keys

The information in one table is related to that in other tables by foreign key relations.

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 that is the primary key for the table)

♦	dept_name (holding the name of the department)

To find out 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 the department ID of the employee's department. This 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.

If a primary key is not assigned, the combination of all columns in the table becomes the primary key. This can lead to a very large transaction log.


Other database objects
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 16. Designing Your Database

Relational database concepts

Other database objects

A relational database holds more than a set of related tables. Among the other objects that make up a SQL Anywhere relational database are:

♦	The index   Indexes allow quick lookup of information

♦	The view   Views are computed tables

♦	The stored procedure and the trigger   These are routines held in the database itself that act on the information in the database

All these objects are in some way built on top of the base tables that hold the information. A base table is a table that is stored permanently in the database. This chapter discusses only how to decide what tables you need and what each table needs to hold.


Planning the database
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 16. Designing Your Database

Planning the database

In designing a database you plan what tables you require and what data they will contain. You also determine how the tables are related.

You must determine what things you want to store information about (each one is an entity) and how these things are related (by a relationship). A useful technique in designing your database is to draw a picture of your tables. This graphical display of a database is called an Entity-Relationship (E-R) diagram. Usually, each box in an E-R diagram corresponds to a table in a relational database, and each line from the diagram corresponds to a foreign key.

Entity-Relationship design

Entity-Relationship design (E-R design) is an example of top-down design of databases. There are now sophisticated methods and tools available to pursue E-R design of databases in great detail. This chapter is an introductory chapter only, but it does contain enough information for the design of fairly straightforward databases.

Entity

Each table in the database describes an entity; it is the database equivalent of a noun. Employees, order items, departments and products are all examples of entities represented by a table in a database. The entities that you build into your database arise from the activities for which you will be using the database, whether that be tracking sales calls, maintaining employee information, or some other activity.

Relationship

A relationship between entities is the database equivalent of a verb. An employee is associated with 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. We will see examples of each in this chapter.

The relationships in the database are an encoding of rules or practices governing the data in the table. If each department has one department head, then a single column can be built into the department table to hold the name of the department head. When these rules are built into the structure of the database, there is no provision for exceptions: there is nowhere to put a second department head, and duplicating the department entry would involve duplicating the department ID, which is the primary key. This is not allowed.

Relationships between tables

There are three kinds of relationships between tables:

♦	One-to-many relationships

♦	One-to-one relationships

♦	Many-to-many relationships


The design process
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 16. Designing Your Database

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 information about implementing the database design, see the chapter "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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 16. Designing Your Database

The design process

Step 1: identify entities and relationships

 To identify the entities in your design and their relationship to each other:

1	Define high-level activities. Identify the general activities you will use this database for. 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 will become tables. 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 tables. For example, there is a relationship between departments and employees. We give this relationship a name.

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

♦	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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 16. Designing Your Database

The design process

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

We can identify the subject areas (tables) and relationships that will hold the information and create a diagram based on the description and high-level activities.

We use boxes to show tables and diamonds to show relationships. We can also identify which relationships are one-to-many, one-to-one, and many-to-many.

This is a rough E-R diagram. It will be refined throughout the chapter.

Break down the high-level activities

The 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

♦	Add a skill for an employee

♦	Identify skills for 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 10.

♦	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 20 skills

♦	An employee may or may not be assigned to an office


Step 2: identify the required data
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 16. Designing Your Database

The design process

Step 2: identify the required data

 To identify the required data:

1	Identify supporting data.

2	List all the data you will need to keep track of. The data that describes the table (subject) answers the questions who, what, where, when, and why.

3	Set up data for each table.

4	List the available data for each table as it seems appropriate right now.

5	Set up data for each relationship.

6	List the data that applies to each relationship (if any).

Identify supporting data

The supporting data you identify will become the names of the columns in the table. For example, the data below might apply to the Employee table, the Skill table, and the Expert In table:

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 like this:

Things to remember

♦	When you are identifying the supporting data, be sure to refer to the activities you identified earlier to see how you will need to access the data.

♦	For example, if you know that you will need a list of all employees sorted by last name, make sure that you specify supporting data as Last name and First name, rather than simply Name (which would contain both first and last names).

♦	The names you choose should be consistent. 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 piece of data, you should not use the full name (Employee_ID) for another piece of data. Instead, the names should be Emp_status and Emp_ID.

♦	It is not crucial that the data be associated with the correct table. You can use your intuition. In the next section, you'll apply tests to check your judgment.


Step 3: normalize the data
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 16. Designing Your Database

The design process

Step 3: normalize the data

Normalization is a series of tests you use to eliminate redundancy in the data and make sure the data is associated with the correct table or relationship. There are five tests. In this section, we will talk about the three tests that are usually used.

For more information about the normalization tests, see a book on database design.

Normal forms

Normal forms are the tests you usually use to normalize data. 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.

 To normalize the data:

1	List the data:

2	Identify at least one key for each table. Each table must have a primary key.

3	Identify keys for relationships. The keys for a relationship are the keys from the two tables it joins.

4	Check for calculated data in your supporting data list. Calculated data is not normally stored in the database.

5	Put data in first normal form:

6	Remove repeating data from tables and relationships.

7	Create one or more tables and relationships with the data you remove.

8	Put data in second normal form:

9	Identify tables and relationships with more than one key.

10	Remove data that depends on only one part of the key.

11	Create one or more tables and relationships with the data you remove.

12	Put data in third normal form:

13	Remove data that depends on other data in the table or relationship and not on the key.

14	Create one or more tables and relationships with the data you remove.

Data and keys

Before you begin to normalize (test your data), simply list the data and identify a unique primary key for each table. The key can be made up of one piece of data (column) or several (a concatenated key).

The primary key is the set of columns that uniquely identifies rows in a table. The primary key for the Employee table is the Employee ID column. The primary key for the Works In relationship consists of the Office Code and Employee ID columns. Give a key to each relationship in your database by taking the key from each of the tables it connects. In the example, the keys identified with an asterisk are the keys for the relationship:

Relationship	Key
Office	*Office code
	Office address
	Phone number
Works in	*Office code
	*Employee ID
Department	*Department ID
	Department name
Heads	*Department ID
	*Employee ID
Assoc with	*Department ID
	*Employee ID
Skill	*Skill ID
	Skill name
	Skill description
Expert in	*Skill ID
	*Employee ID
	Skill level
	Date acquired
Employee	*Employee ID
	Employee last name
	Employee first name
	Social security number
	Employee street
	Employee city
	Employee state
	Employee phone
	Date of birth
Putting data in first normal form

♦	Remove repeating groups.

♦	To test for first normal form, remove repeating groups and put them into a table of their own.

♦	In the example below, Phone number can repeat. (An office can have more than one telephone number.) Remove the repeating group and make a new table called Telephone. Set up a relationship called Associated With between Telephone and Office.

Putting data in second normal form

♦	Remove data that does not depend on the whole key.

♦	Look only at tables and relationships that have more than one key. To test for second normal form, remove any data that does not depend on the whole key (all the columns that make up the key).

♦	In this example, the original Employee table specifies a key composed of two columns. Some of the data does not depend on the whole key; for example, the department name depends on only one of those keys (Department ID). Therefore, the Department ID, which the other employee data does not depend on, is moved to a table of its own called Department, and a relationship called Assigned To is set up between Employee and Department.

Putting data in third normal form

♦	Remove data that doesn't depend directly on the key.

♦	To test for third normal form, remove any data that depends on other data rather than directly on the key.

♦	In this example, the original Employee table contains data that depends on its key (Employee ID). However, data such as office location and office phone depend on another piece of data, Office code. They do not depend directly on the key, Employee ID. Remove this group of data along with Office code, which it depends on, and make another table called Office. Then we will create a relationship called Works In that connects Employee with Office.


Step 4: resolve the relationships
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 16. Designing Your Database

The design process

Step 4: resolve the relationships

When you finish the normalization process, your design is almost complete. All you need to do is resolve the relationships.

Resolving relationships that carry data

Some of your relationships may carry data. This situation often occurs in many-to-many relationships.

When this is the case, change the relationship to a table. The key to the new table remains the same as it was for the relationship.

Resolving relationships that do not carry data

In order to implement relationships that do not carry data, you need to 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.

There are some basic rules that help you decide where to put the keys:

One to many   In a one-to-many relationship, the primary key in the one is carried in the many. In this example, the foreign key goes into the Employee table.

One to one   In a one-to-one relationship, the foreign key can go into either table. If it is mandatory on one side, but not on the other, it should go on the mandatory side. In this example, the foreign key (Head ID) is in the Department table because it is mandatory there.

Many to many   In a many-to-many relationship, a new table is created with two foreign keys. The existing tables are now related to each other through this new table.


Step 5: verify the design
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 16. Designing Your Database

The design process

Step 5: verify the design

Before you implement your design, you need to make sure it supports your needs. Examine the activities you identified at the start of the design process and make sure you can access all the data the activities require:

♦	Can you find a path to get all the information you need?

♦	Does the design meet your needs?

♦	Is all the required data available?

If you can answer yes to all the questions above, you are ready to implement your design.

Final design

The final design of the example looks like this:

  For more information about creating a database in PowerBuilder or InfoMaker, see the PowerBuilder User's Guide or InfoMaker User's Guide.


Designing the database table properties
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 16. Designing Your Database

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

 Choosing data types for columns

 Choosing constraints

 Choosing primary and foreign keys


Choosing column names
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 16. Designing Your Database

Designing the database table properties

Choosing column names

Column names can be any set of letters, numbers or symbols. However, if the column name contains characters other than letters, numbers, or underscores, or it does not begin with a letter, or it is a keyword (see "Alphabetical list of keywords"), then whenever the column name is used, it must be enclosed in double quotes.


Choosing data types for columns
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 16. Designing Your Database

Designing the database table properties

Choosing data types for columns

The data types supported by SQL Anywhere include:

♦	Integer data types (int, integer, smallint)

♦	Decimal data types (decimal, numeric)

♦	Floating-point data types (float, double)

♦	Character data types (char, varchar, long varchar)

♦	Binary data types (binary, long binary)

♦	Date/time data types (date, time and timestamp)

♦	User-defined data types

For a description of data types, see the section "SQL Anywhere Data Types". 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. In the case of CHAR, the maximum length of a value in the column must be specified.

The long binary data type can be used to hold 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 a complete description of each data type, see "SQL Anywhere Data Types".

NULL and NOT NULL

When 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; you should explicitly declare columns to be NOT NULL unless there is a good reason to allow NULL values.

For a complete description of the NULL value, see "NULL value". For information on its use in comparisons, see "Search conditions".


Choosing constraints
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 16. Designing Your Database

Designing the database table properties

Choosing constraints

Although the data type of a column restricts the values 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, although most CHECK constraints use either the BETWEEN or IN conditions.

  For more information

For more information about valid conditions, see "Search conditions". For more information about assigning constraints to tables and columns, see the chapter "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	—	not null	None
Notice that "not null" is specified for each column. In this case, data for all columns is required for every row in the table.


Choosing primary and foreign keys
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 16. Designing Your Database

Designing the database table properties

Choosing primary and foreign keys

The primary key is the column or columns that uniquely identify the rows in the table. If your tables are properly normalized, a primary key should be defined as part of the database design.

A foreign key is a column or set of columns that contains primary key values from another table. Foreign key relationships build one-to-one and one-to-many relationships into your database. If your design is properly normalized, foreign keys should be defined as part of your database design.


Working with Database Objects
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 17. Working with Database Objects

About this chapter

This chapter describes the mechanics of creating, altering, and modifying database objects. The set of definitions of the database objects form the database schema: you can think of the schema as the database without any data.

This chapter also discusses creating and working with other database objects, (such as indexes and views).

Procedures and triggers are also database objects, and are discussed in the chapter "Using Procedures, Triggers, and Batches".

 Using Sybase Central to work with database objects

 Using ISQL to work with database objects

 Working with databases

 Working with tables

 Working with views

 Working with indexes


Using Sybase Central to work with database objects
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 17. Working with Database Objects

Using Sybase Central to work with database objects

Sybase Central is the primary tool for working with database objects in SQL Anywhere. You can use SQL Anywhere to create, modify, and delete all kinds of database objects, including tables, procedures, triggers, views, indexes, users and groups, and so on.

This chapter is concerned with the SQL statements for working with database objects. If you are using Sybase Central, these SQL statements are generated for you. The primary source of information about Sybase Central is the Sybase Central online Help. In this chapter, only brief pointers are given for tasks you can carry out using Sybase Central.

For an introduction to using Sybase Central, see the chapter "Managing Databases with Sybase Central".


Using ISQL to work with database objects
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 17. Working with Database Objects

Using ISQL to work with database objects

ISQL is a utility for entering SQL statements, supplied with SQL Anywhere. If you are using ISQL to work with your database schema, instead of executing the SQL commands one at a time, you should build up the set of commands in an ISQL command file. This file can then be executed in ISQL to build the database.

If you are using a tool other than ISQL, all the information in this chapter concerning SQL statements still applies.

If you have not created your database using command files, you can create a command file that would recreate your database by unloading the database.

  For a description of the DBUNLOAD utility, see "The Unload utility".

ISQL command file

An ISQL command file is a text file with semicolons placed at the end of commands (see the chapter "Command Files") as shown below.

CREATE TABLE t1 ( .. );

CREATE TABLE t2 ( .. );

CREATE INDEX i2 ON t2 ( .. );

..

An ISQL command file is usually given a name with the extension SQL. To create your database using a command file, you can either paste it into the ISQL command window (for files with less than 500 lines), or execute the saved command file by entering a command to read the file into the ISQL command window. For example:

read makesdb

will read the ISQL commands in the file MAKEDB.SQL.


Working with databases
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 17. Working with Database Objects

Working with databases

Some application design systems, such as Powersoft PowerBuilder, contain facilities for creating databases. These tools construct SQL statements that are submitted to the SQL Anywhere engine, 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 supported by SQL Anywhere. You can use these statements directly if you are building your database from an Interactive SQL tool, such as ISQL. 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 system's database design tool.

 Initializing a database

 Adding database files

 Preallocating space for database files

 Erasing a database


Initializing a database
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 17. Working with Database Objects

Working with databases

Initializing a database

Initializing a database creates the root file for storing your database and the system tables, which hold the schema definition as you build your database.

Database files are compatible among all versions of SQL Anywhere. A database created from any operating system can be used from another operating system by copying the database file(s). A database created with a standalone database engine can be used with any SQL Anywhere network server as long as the server is not an earlier release.

You create a database using the database initialization utility. Database initialization is not controlled by SQL statements. Once the database is initialized, you can connect to it and build the objects in the database using SQL statements. If you are using Sybase Central, the SQL statements are constructed for you and you do not have to enter them yourself.

Accessing the initialization utility

A full description of the initialization utility, with the options available when you create a database is given in "The Initialization utility". The initialization utility can be accessed in the following ways:

♦	In Sybase Central, click the Database Utilities folder in the left panel, then double-click Create Database to start the Create Database Wizard, which leads you through the process.

♦	For Windows 3.x and OS/2, use the ISQL Database Tools window. To open this window, select the Database Tools menu item from the Window menu. Select Create Database from the Tools list, and enter the path and name of the file in which you wish to store the database in the Database File field. It is recommended that you give the database file the standard filename extension of DB. Press the Create button. This displays another dialog box for specifying options such as page size and collation sequence.

♦	Use the DBINIT command (DBINITW for Windows). For a full description of the DBINIT command, see "The Initialization utility".

For example, the following command will create a database called COMPANY.DB:

dbinit company.db

♦	Command line parameters allow different options for the database. For example, the following command creates a database with a 4K page size:

dbinit -p 4096 company.db

♦	Use the ISQL DBTOOL statement. The database utility programs are available from within ISQL using the DBTOOL command. For example, the following command creates a database called COMPANY.DB:

DBTOOL CREATE DATABASE 'company.db'

♦	The following command creates a database with 4K pages:

DBTOOL CREATE DATABASE 'company.db' PAGE SIZE 4096


Adding database files
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 17. Working with Database Objects

Working with databases

Adding database files

When a database is initialized, it is composed of one file. This first database file is called the root file. All database objects and all data are placed in the root file. For many databases, it is convenient to keep the database as a single file. This section is intended only for users of large databases.

Each SQL Anywhere database file has a maximum size of 2 GB, so you may wish to divide large databases among more than one file. (On Windows NT, this limitation is removed, and files can be up to a terabyte). You create a new database file, or dbspace, using the CREATE DBSPACE statement. A new dbspace may be on the same disk drive as the root file or on another disk drive. You must have DBA authority to create new database files.

When created, a new dbspace has no contents. When you create a new table you can place it in the new dbspace with an IN clause in the CREATE TABLE statement. For information on creating tables, see "Creating tables". If no IN clause is used, the table is placed in the root file. Each table must be contained in a single dbspace, and SQL Anywhere has a maximum of twelve dbspaces per database. By default, indexes are placed in the same dbspace as their table, but they can be placed in a separate dbspace by supplying an IN clause.

Example

The following command creates a new dbspace called library in the file LIBRARY.DB in the same directory as the root file:

CREATE DBSPACE library

AS 'library.db'

To create a table and place it in the library dbspace, you can use the following command:

CREATE TABLE Library_Books (

title char(100),

author char(50),

isbn char(30)

) IN library

If you wish to split existing database objects among several dbspaces, you need to unload your database and modify the 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 root file.

Creating a dbspace in Sybase Central

 To create a dbspace in Sybase Central:

1	Connect to the database.

2	Click the DB Spaces folder for that database.

3	Double-click Add DB Space in the right panel.

4	Enter the dbspace name and filename

5	Click OK to create the dbspace.


Preallocating space for database files
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 17. Working with Database Objects

Working with databases

Preallocating space for database files

SQL Anywhere automatically takes new disk space for database files as needed. Unless you are working with a large database with a high rate of inserts and deletes, you do not need to worry about explicitly allocating spaced for database files. SQL Anywhere does allow preallocation of disk space for database files or for transaction logs for those cases where rapidly changing database files could lead to excessive file fragmentation on the disk, and possible performance problems.

You can preallocate disk space for a database file or for the transaction log using the ALTER DBSPACE statement. For more information on this statement, see "ALTER DBSPACE statement".

For example, the following statement adds 200 pages to the database file with dbspace name library. (The database page size is fixed when the database is created.)

ALTER DBSPACE library

ADD 200

Running a disk defragmentation utility after preallocating 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.

Preallocating disk space in Sybase Central

 To preallocate disk space for a dbspace in Sybase Central:

1	Connect to the database.

2	Click the DB Spaces folder for that database.

3	Double-click the dbspace in the right panel.

4	Click Add Pages, and enter the number of database pages to preallocate.

5	Click OK.


Erasing a database
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 17. Working with Database Objects

Working with databases

Erasing a database

Erasing a database deletes all tables and data from disk, including the transaction log that records alterations to the database.

All SQL Anywhere databases are marked as read-only to prevent accidental modification or deletion of the database files.

You can erase database files using the Erase utility. For a full description of the Erase utility, see "The Erase utility".

Accessing the Erase utility

You can access the Erase utility using any of the following methods:

♦	Using Sybase Central. Click the Database Utilities folder, and double-click Erase Database to display the Erase Database Wizard, which leads you through the process.

♦	Using the ISQL Database Tools window. To open this window, select the Database Tools menu item from the Window menu. Select Erase Database or Write File from the Tools list, and enter the name of the database file in the Database File field. The database is erased when you press the Erase button.

♦	Using the DBERASE command-line utility (DBERASEW for Windows). The following command erases the database company.db and its transaction log:

dberase company.db

You will be asked to confirm that you really want to erase the files. To erase the files, type y and press ENTER.

♦	Using the DBTOOL statement. All the database utility programs are available from within ISQL using DBTOOL. For example, the following command erases the database company.db and its transaction log: DBTOOL DROP DATABASE company.db

The Erase utility can also be used to erase write files and log files. For a description of write files, see "The Write File utility".


Working with tables
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 17. Working with Database Objects

Working with tables

When the database is initialized, the only tables in the database are the system tables which hold the database schema.

This section describes how to create, alter, and delete tables from a database The examples can be executed in ISQL, but the SQL statements are independent of the administration tool you are using.

You should create command files containing the CREATE TABLE and ALTER TABLE statements that define the tables in your database.

 Creating tables

 Altering tables

 Deleting tables

 Creating primary and foreign keys

 Table information in the system tables


Creating tables
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 17. Working with Database Objects

Working with tables

Creating tables

Creating tables in Sybase Central

To create a table in Sybase Central you first create an empty table, and then add columns, specify primary keys and constraints, and so on:

 To create an empty table:

1	Connect to the database.

2	Click the Tables folder for that database.

3	Double-click Add Table in the right panel.

4	Fill out the dialog box.

5	Click OK to create an empty table.

 To add a column to a table:

1	Double-click the new table.

2	Double-click the Columns folder.

3	Double-click Add Column.

4	Fill out the dialog box.

5	Click OK to the column.

Creating tables in ISQL

There are two ways to create new tables using ISQL:

♦	Type a CREATE TABLE statement in ISQL.

♦	Create a command file that contains the CREATE TABLE commands for your database. (This allows you easily to recreate your database and provides some documentation of the structure of your database)

This section describes how to create tables interactively using ISQL. The examples in this section use the sample database. To try the examples, run ISQL and connect to the sademo.db database with userid dba and password SQL.

For information on connecting to a database from ISQL, see "Connecting from the SQL Anywhere utilities".

You can create tables from other tools in addition to ISQL. The SQL statements described here are independent of the tool you are using.

The following command 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 (say 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

)

You can execute this command by typing it into the ISQL command window. and pressing the execute key (F9). Note the following:

♦	Each column has a data type. The skill_id is an integer (like 101), the skill_name is a character string containing up to 20 characters, and so on.

♦	All columns are mandatory as indicated by the phrase NOT NULL after their data types.

Before creating the table, SQL Anywhere makes all previous changes to the database permanent by internally executing the COMMIT statement. There is also a COMMIT after the table is created.

For a full description of the CREATE TABLE statement, see "CREATE TABLE statement". For information about building constraints into table definitions using CREATE TABLE, see the chapter "Ensuring Data Integrity".


Altering tables
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 17. Working with Database Objects

Working with tables

Altering tables

This section describes how to change the structure of a table using the ALTER TABLE statement.

Example 1

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.

Example 2

Column attributes can also be modified 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 is displayed.

Example 3

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

DELETE classification

Example 4

As a final example, 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—foreign keys can be added or deleted, columns can be changed from one type to another, and so on.

For a complete description of the ALTER TABLE command, see "ALTER TABLE statement". For information about building constraints into table definitions using ALTER TABLE, see the chapter "Ensuring Data Integrity".

Altering tables in Sybase Central

The property sheets for tables and columns display all the table or column attributes. You can alter a table definition in Sybase Central by displaying the property sheet for the table or column you wish to change, altering the property, and clicking OK to commit the change.


Deleting tables
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 17. Working with Database Objects

Working with tables

Deleting tables

The following DROP TABLE command deletes all the records in the Absence table and then removes the definition of the Absence table from the database

DROP TABLE skill

Like the CREATE command, the DROP command automatically executes a COMMIT statement before and after dropping the table. This makes all changes to the database since the last COMMIT or ROLLBACK permanent.

For a full description of the DROP statement, see "DROP statement".

 To drop a table in Sybase Central:

1	Connect to the database.

2	Click the Tables folder for that database.

3	Right-click the table you wish to delete, and select Delete from the popup menu.


Creating primary and foreign keys
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 17. Working with Database Objects

Working with tables

Creating primary and foreign keys

The CREATE TABLE and ALTER TABLE statements allow many attributes of tables to be set, including column constraints and checks. This section shows how to set table attributes using the primary and foreign keys as an example.

Creating a primary key

The following statement creates the same skill table as before, except that a primary key is added:

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.

Creating a primary key in Sybase Central

Columns in the primary key are not allowed to contain the NULL value. You must specify NOT NULL on the column in the primary key.

 To create a primary key in Sybase Central:

1	Connect to the database.

2	Click the Tables folder for that database.

3	Right-click the table you wish to modify, and select Properties from the popup menu, to display its property sheet.

4	Click the Columns tab, and add columns to the primary key, or remove them from the primary key.

For more information, see the Sybase Central online Help.

Creating foreign keys

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 may appear several times. However, there may be no more than one entry for a given employee's level at a particular skill:

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, and that the skill_id must contain a valid entry from the skill table.

The skill level contains a space and is surrounded by quotation marks ("double quotes"). SQL Anywhere allows column names and table names to contain any characters, but the names must be enclosed in quotation marks if any characters other than letters, digits or underscore are used, or if the name does not begin with a letter, or if the name is a keyword.

Single and double quotes in SQL

Remember, in SQL:

♦	Single quotes (apostrophes) are used to indicate database values (for example, 'SMITH', '100 Apple St.', '1988-1-1').

♦	Double quotes (quotation marks) are used to indicate table or column names (for example, "skill level", "emp_id", "skill_type").

♦	To include a single quote inside a string, use two single quotes:

'''Plankton'' said the cat'

A table can only have one primary key defined, but it may have as many foreign keys as necessary.

For more information about using primary and foreign keys, see the chapter "Ensuring Data Integrity".

Creating a foreign key in Sybase Central

 create a foreign key in Sybase Central:

1	Connect to the database.

2	Click the Tables folder for that database.

3	Click the primary key table, and drag it to the foreign key table.

4	When the primary key table is dropped on the foreign key table, the Foreign Key Wizard is displayed, which leads you through the process of creating the foreign key.

For more information, see the Sybase Central online Help.


Table information in the system tables
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 17. Working with Database Objects

Working with tables

Table information in the system tables

All the information about tables in a database is held in the system tables. The information is distributed among several tables. For more information, see "SQL Anywhere System Tables".

You can use Sybase Central or ISQL to browse the information in these tables. Type the following command in the ISQL command window to see all the columns in the SYS.SYSTABLE table:

SELECT *

FROM SYS.SYSTABLE

 To display the system tables in Sybase Central:

1	Connect to the database.

2	Right-click the database, and select Show System Objects from the popup menu.

3	When you view the database tables or views with Show System Objects checked, the system tables or views are also shown.


Working with views
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 17. Working with Database Objects

Working with views

Views are computed tables. You can use views to provide to 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 view 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 are recomputed each time they are invoked. Views refer to the information in base tables, but do not hold copies of that information.

Benefits of tailoring access

Views are used to tailor access to data in the database Tailoring access serves several purposes:

♦	Improved security: by not allowing access to information that is not 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

 Permissions on views

 Deleting views

 Views in the system tables


Creating views
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 17. Working with Database Objects

Working with views

Creating views

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.

Example

Suppose that you frequently need to list the number of employees in each department. You can get this list with the following command:

SELECT dept_ID, count(*)

FROM employee

GROUP BY dept_ID

You can create a view containing the results of this command as follows:

CREATE VIEW DepartmentSize AS

SELECT dept_ID, count(*)

FROM employee

GROUP BY dept_ID

The information in a view is not stored separately in the database. Each time you refer to the view, SQL Anywhere 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 will be automatically up to date. On the other hand, if the SELECT command is complicated it may take a long time for SQL to find the correct information every time you use the view.

 To create a view in Sybase Central:

1	Connect to the database.

2	Click the Views folder for that database.

3	Double-click Add View.

4	Enter the CREATE VIEW statement in the Sybase Central editor, and click Execute Script to save the view.

For more information, see the Sybase Central online Help.


Using views
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 17. Working with Database Objects

Working with views

Using views

Restrictions on SELECT statements

There are some restrictions on the SELECT statements that you can use as views. In particular, you cannot use an ORDER BY clause in the SELECT query. It is a characteristic of relational tables 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, you should 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

CREATE VIEW viewname AS

phrase in front of the query to create the view.

Updating views

UPDATE, INSERT, and DELETE statements are allowed on some views, but not on others, depending on its associated SELECT statement.

Views containing aggregate functions, such as COUNT(*), cannot be updated. Views containing a GROUP BY clause in the SELECT statement cannot be updated. Also, views containing a UNION operation cannot be updated. In all these cases, there is no way for the database engine to translate the UPDATE into an action on the underlying tables.


Using the WITH CHECK OPTION clause
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 17. Working with Database Objects

Working with views

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 row or rows in the underlying tables may not meet the requirements for the view itself: the view would have no new rows even though the INSERT or UPDATE does modify the underlying tables.

Examples using the WITH CHECK option clause

The following set of examples illustrates the meaning and usefulness of the WITH CHECK OPTION clause. This optional clause is the final clause in the CREATE VIEW statement.

 To create a view displaying the employees in the sales department.

1	Type the following commands:

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

emp_id	emp_fname	emp_lname	dept_id
129	Philip	Chin	200
195	Marc	Dill	200
299	Rollin	Overbey	200
467	James	Klobucher	200
641	Thomas	Powell	200
The following UPDATE statement modifies this list, but in such a way that the modified row no longer meets the criterion for the view, and so vanishes from the view.

♦	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

♦	font=symbol charset=fontspecific code=168  	descr='[diams]'   List all employees in the sales department.

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
667	Mary	Garcia	200
When a view is created WITH CHECK OPTION, any UPDATE or INSERT statement on the view is checked to ensure that the new row does match 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 an error message "invalid value for column 'dept_id' in table 'employee'".

♦	font=symbol charset=fontspecific code=168  	descr='[diams]'   Create a view displaying the employees in the sales department (second attempt).

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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 17. Working with Database Objects

Working with views

Modifying views

To modify a view, you need to first remove it from the database using the DROP statement, and then create a replacement using the CREATE VIEW statement.

For example, to replace the base table column names with more informative names in the DepartmentSize view, you would first drop the view using the DROP VIEW command (see "Deleting views") and then create a new view with the same name (see "Creating views"):

CREATE VIEW DepartmentSize (Dept_ID, NumEmployees) AS

SELECT dept_ID, count(*)

FROM Employee

GROUP BY dept_ID

Permissions are lost when you modify views—All permissions governing access to the view are lost when you execute the DROP VIEW command. You need to reassign permissions when you modify views.


Permissions on views
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 17. Working with Database Objects

Working with views

Permissions on views

With release 5.0, a change has been made to permissions on views. Before release 5.0, permissions on the underlying tables were required in order for permissions to be granted on views. Permissions can now be granted on views without permissions on the underlying tables.

An INSERT, DELETE, or UPDATE operation is allowed either if permission on the view has been granted or if permission on the underlying tables has been granted. Previously permissions on both the table and the view were required.

UPDATE permissions can be granted only on an entire view. Unlike tables, UPDATE permissions cannot be granted on individual columns within a view.


Deleting views
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 17. Working with Database Objects

Working with views

Deleting views

To delete a view from the database, you use the DROP statement. The following command removes the DepartmentSize view:

DROP VIEW DepartmentSize

Dropping a view in Sybase Central

To drop a view in Sybase Central, right-click the view you wish to delete and select Delete from the popup menu.

For more information, see the Sybase Central online Help.


Views in the system tables
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 17. Working with Database Objects

Working with views

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 "SYS.SYSVIEWS".

You can use ISQL to browse the information in these tables. Type the following command in the ISQL command window 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 command such as the following:

SELECT viewtext FROM SYS.SYSVIEWS

   WHERE viewname = 'Marks';

OUTPUT TO viewtext.sql FORMAT ASCII


Working with indexes
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 17. Working with Database Objects

Working with indexes

Performance is an important consideration when designing and creating your database. Indexes can dramatically improve the performance of database searches (operations using SELECT, UPDATE and DELETE commands) on specified columns.

When to use indexes

An index is similar to a telephone book which first sorts people by their last name, and then sorts all the people with the same last name by their first name. Telephone books are indexed on the last name and first name. This speeds up searches for phone numbers given a particular last name. Just as a standard telephone book is, however, no use at all for finding the phone number at a particular address, so an 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.

Use indexes for frequently-searched columns

Indexes share one other feature with a phone book: they can take up a great deal of space for large data sets. For this reason, you should build indexes only for columns that are searched frequently or when disk space is not an issue.

If a column is already a primary key or foreign key, searches will be fast on this column because SQL Anywhere has facilities to optimize searches on these key columns. Thus, 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.

When indexes on primary keys may be useful—One case where an index on a key column may assist performance is when a large number of foreign keys reference a primary key.  The performance increase is because of SQL Anywhere storage of key indexes.

SQL Anywhere automatically uses indexes to improve the performance of any database command whenever it can. There is no need to refer to indexes once they are created. SQL Anywhere also automatically updates the index when rows are deleted, updated or inserted.

Indexes are created on a specified table. You cannot create an index on a view.

If an index is no longer required, you can remove it from the database using the DROP command.

Example

In order 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)

The following statement removes the index from the database:

DROP INDEX EmpNames

  For more information

♦	For more information about improving database performance, including the use of indexes, see the chapter "Monitoring and Improving Performance".

♦	For a detailed description of the CREATE INDEX command, including syntax and permission requirements, see "CREATE INDEX statement".

♦	For a detailed description of the DROP command, including syntax and permission requirements, see "DROP statement".

Creating and dropping indexes in Sybase Central

 To create an index on a table in Sybase Central:

1	Connect to the database.

2	Double-click the table you wish to modify.

3	Double-click the Indexes folder, and then double-click Add Index.

4	Fill in the dialog box and click OK to complete.

You can drop an index in Sybase Central by right-clicking it, and selecting Delete from the popup menu.

For more information, see the Sybase Central online Help.

 Indexes in the system tables


Indexes in the system tables
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 17. Working with Database Objects

Working with indexes

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 ISQL to browse the information in these tables.


Ensuring Data Integrity
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

About this chapter

This chapter describes SQL Anywhere's facilities for ensuring that the data in your database is valid and reliable. Building integrity constraints right into the database is the surest way to make sure your data stays in good shape.

Several types of integrity constraints can be enforced in SQL Anywhere databases. You can ensure individual entries are correct by imposing constraints and CHECK conditions 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 statement and ALTER TABLE statement, basic forms of which were introduced in the chapter "Working with Database Objects".

 Data integrity overview

 Using column defaults

 Using table and column constraints

 Enforcing entity and referential integrity

 Integrity rules in the system tables


Data integrity overview
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Data integrity overview

For data to have integrity means that the data is valid—correct and accurate—and that the relational structure of the database is intact. The relational structure of the database is enforced through referential integrity constraints. These are rules that maintain the consistency of data between tables.

SQL Anywhere supports stored procedures, which allow you detailed control over how data gets entered into the database. SQL Anywhere also allows you to create triggers: custom procedures stored in the database that are invoked automatically when a certain action, such as an update of a particular column, is carried out. Procedures and triggers are discussed in the chapter "Using Procedures, Triggers, and Batches".

 How data can become invalid

 Integrity constraints belong in the database

 How database contents get changed

 Data integrity tools in SQL Anywhere

 SQL statements for implementing integrity constraints


How data can become invalid
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Data integrity overview

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. Each of these examples can be prevented by SQL Anywhere facilities described in this chapter.

Examples

♦	Incorrect information

♦	A sales transaction takes place, but the operator entering the date of the transaction does so incorrectly

♦	A zero is missed off a salary entry, making an employee's salary ten times too small

♦	Duplicated data

♦	A new department has been created, with dept_id 200, and needs to be added to the department table of the organization's database—but two people enter this information into the table

♦	Foreign key relations invalidated

♦	In a reorganization, the department identified by dept_id 300 is closed down.

Each employee record for employees in this department is given a new dept_id entry, and then the department 300 row is deleted from the department table. But one employee was missed, and still has dept_id 300 in their record.


Integrity constraints belong in the database
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Data integrity overview

Integrity constraints belong in the database

In order to ensure that the data in a database are valid, you need to formulate checks that define valid and invalid data and design rules to which data must adhere. The rules to which data must conform are often called business rules. The collective name for checks and rules is constraints.

Build integrity constraints into database

Constraints built in to the database itself are inherently more reliable than those built in to client applications, or spelled out as instructions to database users. Constraints built into the database are part of the definition of the database itself and enforced consistently across all applications.

Setting a constraint once, in the database, imposes it for all subsequent interactions with the database, no matter from what source. In contrast, constraints built into client applications are vulnerable every time the software is altered, and may need to be imposed in several applications, or several places in a single client application.


How database contents get changed
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Data integrity overview

How database contents get changed

Information in SQL Anywhere database tables is changed by submitting SQL statements from client applications. Only a few SQL statements actually modify the information in a database.

♦	Information in a row of a table may be updated, using the UPDATE statement.

♦	An existing row of a table may be deleted, using the DELETE statement.

♦	A new row may be inserted into a table, using the INSERT statement.


Data integrity tools in SQL Anywhere
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Data integrity overview

Data integrity tools in SQL Anywhere

To assist in maintaining data integrity, SQL Anywhere provides defaults, data constraints, and constraints that maintain the referential structure of the database.

Defaults

SQL Anywhere allows you to assign default values to columns, to make certain kinds of data entry more reliable. For example:

♦	A column can have a current date default for recording the date of transactions with any user or client application action.

♦	A particular kind of default allows column values to be incremented automatically whenever a new row is entered. Items such as purchase orders, for example, can be guaranteed unique sequential numbers in this way without any user action.

These and other column defaults are discussed in "Using column defaults".

Constraints

SQL Anywhere also supports several types of constraints on the data in individual columns or tables. For example:

♦	A NOT NULL constraint prevents a column from containing a null entry.

♦	Columns can have CHECK conditions assigned to them, to ensure that a particular condition is met by every item in the column. You could ensure, for example, that salary column entries are within a specified range, protecting against user error when typing in new values.

♦	CHECK conditions can be made on the relative values in different columns, to ensure, for example, that in a library database a date_returned entry is later than a date_borrowed entry.

♦	More sophisticated CHECK conditions can be enforced using a trigger. Triggers are discussed in the chapter "Using Procedures, Triggers, and Batches".

These and other table and column constraints are discussed in "Using table and column constraints". Column constraints can be inherited from user-defined data types.

Entity and referential integrity

The information in relational database tables is tied together by the relations between tables. These relations are defined by the primary keys and foreign keys built in to the database design. SQL Anywhere supports two integrity rules that 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 no nulls.

♦	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.

In addition, SQL Anywhere provides triggers. A trigger is a procedure stored in the database that is executed automatically whenever the information in a specified table is altered. Triggers are a powerful mechanism for database administrators and developers to ensure that data is kept reliable. Triggers are discussed in the chapter "Using Procedures, Triggers, and Batches".

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 the chapter "Designing Your Database".


SQL statements for implementing integrity constraints
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Data integrity overview

SQL statements for implementing integrity constraints

The following SQL statements are used to implement integrity constraints:

CREATE TABLE statement   This statement is used to implement integrity constraints as the database is being created.

ALTER TABLE statement   This statement is used to add integrity constraints to an existing database, or to modify constraints for an existing database.

CREATE TRIGGER statement   This statement is used to create triggers to enforce more complex business rules.

For full descriptions of the syntax of these statements, see the chapter "Watcom-SQL Language Reference".


Using column defaults
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Using column defaults

Column defaults automatically assign a specified value to particular columns when a new row is entered into a database table, without any action on the part of the client application, as long as no value is specified by the client application. If the client application does specify a value for the column, it overrides the column default value.

Column defaults are useful for filling columns that contain information such as the date or time a row is inserted, or the user ID of the person entering the information, that is available to the computer automatically.

Using column defaults encourages data integrity, but does not enforce it. Defaults can always be overridden by client applications.

Supported default values

The following default values are supported:

♦	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 value, one more than the previous highest value in the column

♦	The current date, or 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 NULL default

 String and number defaults

 Constant expression defaults


Creating column defaults
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Using column defaults

Creating column defaults

Column defaults can be created at the time a table is created, using the CREATE TABLE statement, or added at a later time using the ALTER TABLE statement.

Example

The following statement adds a condition to an existing column named id in the sales_order table, so that it is automatically incremented (unless a value is specified by a client application):

ALTER TABLE sales_order

MODIFY id DEFAULT AUTOINCREMENT

Each of the other default values is specified in a similar manner. For a detailed description of the syntax, see "CREATE TABLE statement".


Modifying and deleting column defaults
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Using column defaults

Modifying and deleting column defaults

Column defaults can be changed or removed by using the same form of the ALTER TABLE statement as 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

Column defaults are removed 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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Using column defaults

Working with column defaults in Sybase Central

All adding, altering, and deleting of column defaults in Sybase Central is carried out in the Type tab of the column properties sheet.

 To display the property sheet for a column:

1	Connect to the database.

2	Click the Tables folder for that database, and click the table holding the column you want to change.

3	Double-click the Columns folder to open it, and double-click the column to display its property sheet.

For more information, see the Sybase Central online Help.


Current date and time defaults
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Using column defaults

Current date and time defaults

For columns with the DATE, TIME, or TIMESTAMP data type, the current date, current time, or current timestamp may be used as a default. The default specified must be compatible with the column's data type.

Useful examples of current date default

The following are just a few examples of when a current date default would be useful:

♦	To record dates of phone calls and contacts in contact databases

♦	To record the dates of orders in sales entry databases

♦	To record the date a book is borrowed in a library database

Current timestamp

The current timestamp is used for similar purposes as the current date default, but when greater accuracy is required. For example, a user of a contact management application may have several contacts with a single customer in one day: the current time default would be useful to distinguish these contacts.

The current timestamp is also useful when the sequence of events is important in a database, as it records a date and the time down to a precision of millionths of a second.

For more information about timestamps, times and dates, see "SQL Anywhere Data Types".


The user ID default
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Using column defaults

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 applications for occasionally connected users. These users can make a copy of tables relevant to their work on a portable computer, make changes while not connected to a multiuser database, and then apply the transaction log to the server when they return. Incorporating their user ID into the primary key of the table helps to prevent the chance of conflicts during the update.


The autoincrement default
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Using column defaults

The autoincrement default

The autoincrement default assigns each new row a value one greater than that of the previous highest value in the column. Autoincrement columns can be used to record purchase order numbers, to identify customer service calls, or other entries where an identifying number is required, but where the value of the number itself has no meaning.

Autoincrement columns are typically primary key. columns or columns constrained to hold unique values (see "Enforcing entity integrity"). It is highly recommended that the autoincrement default not be used in cases other than these, as doing so can adversely affect the database performance. One case when an autoincrement default does not adversely affect performance is when the column is the first column of an index. This is because the engine uses an index or key definition to find the highest value.

The next value to be used for each column is stored as a long integer (4 bytes). Using values greater than (2**31 - 1), that is, large double or numeric values, may cause wraparound to negative values, and AUTOINCREMENT should not be used in such cases.


The NULL default
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Using column defaults

The NULL default

For columns that allow NULL values, specifying a NULL default is exactly the same as not specifying a default at all: a NULL value is assigned to the column if no value is explicitly assigned by the client when inserting the row.

NULL defaults are typically used when information for some columns is optional or not always available and is not required for the data in the database be correct.

For more information on the NULL value, see "NULL value".


String and number defaults
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Using column defaults

String and number defaults

A specific string or number can be specified 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 same data type as 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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Using column defaults

Constant expression defaults

A constant expression can be used as a default value, as long as it does not reference database objects.  This allows column defaults to contain entries such as "fifteen days from today", which would be entered as

... DEFAULT ( dateadd( day, 15, getdate() ) )


Using table and column constraints
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Using table and column constraints

The CREATE TABLE statement and ALTER TABLE statement can specify many different attributes for a table. Along with the basic table structure (number, name and data type of columns, name and location of the table), you can specify other features that allow control over data integrity.

 Caution—Altering tables can interfere with other users of the database. Although the ALTER TABLE statement can be executed while other connections are active, it is prevented if any other connection is using the table to be altered. For large tables, ALTER TABLE is a time consuming operation, and no other requests referencing the table being altered are allowed while the statement is being processed.

This section describes how to use constraints to help ensure that the data entered in the table is correct.

 Using CHECK conditions on columns

 Column CHECK conditions from user-defined data types

 Working with column constraints in Sybase Central

 Using CHECK conditions on tables

 Modifying and deleting CHECK conditions


Using CHECK conditions on columns
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Using table and column constraints

Using CHECK conditions on columns

A CHECK condition can be applied to values in a single column, to ensure that they satisfy rules. These rules may be rules that data must satisfy in order to be reasonable, or they may be more rigid rules that reflect organization policies and procedures.

You use a CHECK condition to ensure that the values in a column satisfy some definite criterion.

CHECK conditions on individual column values are useful when only a restricted range of values are valid for that column. Here are some examples:

Example 1

♦	You can enforce a particular formatting requirement. If a table has a column for phone numbers you may wish to ensure that they are all entered in the same manner. For North American phone numbers, you could use a constraint such as the following:

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 like the following:

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 want to require that the start_date column of an employee table must be between the date the organization was formed and the current date. This could be achieved as follows:

ALTER TABLE employee

MODIFY start_date

CHECK ( start_date BETWEEN '1983/06/27'

AND CURRENT DATE )

♦	SQL Anywhere supports several date formats: the YYYY/MM/DD format used 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 a value of UNKNOWN is returned, the change is allowed.

Column CHECK conditions in previous releases—There is a change in the way that column CHECK conditions are held in this release. In previous releases, column CHECK conditions were merged together with all other CHECK conditions on a table into a single CHECK condition. Consequently, they could not be individually replaced or deleted. In this release, column CHECK conditions are held individually in the system tables, and can be replaced or deleted individually. Column CHECK conditions added before this release are still held in a single table constraint, even if the database is upgraded.


Column CHECK conditions from user-defined data types
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Using table and column constraints

Column CHECK conditions from user-defined data types

You can attach CHECK conditions to user-defined data types, and columns defined on those data types inherit the CHECK conditions. A CHECK condition explicitly specified for the column overrides that from the user-defined data type.

When defining a CHECK condition on a user-defined data type, any variable prefixed with the @ sign is replaced by the name of the column when the CHECK condition is evaluated. For example, the following user-defined data type accepts only positive integers:

CREATE DATATYPE posint INT

CHECK ( @col > 0 )

Any variable name prefixed with @ could be used instead of @col. Any column defined using the posint data type accepts only positive integers unless it has a CHECK condition explicitly specified.

An ALTER TABLE statement with the DELETE CHECK clause deletes all CHECK conditions from the table definition, including those inherited from user-defined data types.

For information on user-defined data types, see "User-defined data types".


Working with column constraints in Sybase Central
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Using table and column constraints

Working with column constraints in Sybase Central

All adding, altering, and deleting of column constraints in Sybase Central is carried out in the Constraints tab of the column properties sheet.

 To display the property sheet for a column:

1	Connect to the database.

2	Click the Tables folder for that database, and click the table holding the column you wish to change.

3	Double-click the Columns folder to open it, and double-click the column to display its property sheet.

For more information, see the Sybase Central online Help.


Using CHECK conditions on tables
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Using table and column constraints

Using CHECK conditions on tables

A CHECK condition can be applied as a constraint on the table, instead of on a single column. Such CHECK conditions typically ensure that two values in a row being entered or modified have a proper relation to each other. Column CHECK conditions are held individually in the system tables, and can be replaced or deleted individually. This is more flexible behavior, and CHECK conditions on individual columns are recommended where possible.

For example, in a library database, the date_returned column for a particular entry must be later than (or the same as) the date_borrowed entry:

ALTER TABLE loan

ADD CHECK(date_returned >= date_borrowed)


Modifying and deleting CHECK conditions
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Using table and column constraints

Modifying and deleting CHECK conditions

There are several ways of altering the existing set of CHECK conditions on a table.

♦	You can add a new CHECK condition to the table or to an individual column, as described above.

♦	You can delete a CHECK condition on a column by setting it to NULL. The following statement removes the CHECK condition on the phone column in the customer table: ALTER TABLE customer MODIFY phone CHECK NULL

♦	You can replace a CHECK condition on a column in the same was as adding a CHECK condition. The following statement adds or replaces a CHECK condition on the phone column of the customer table:

ALTER TABLE customer

MODIFY phone

CHECK ( phone LIKE '___-___-____' )

♦	There are two ways of modifying a CHECK condition defined on the table, as opposed to a CHECK condition defined on a column.

♦	You can add a new CHECK condition using ALTER TABLE with an ADD table-constraint clause.

♦	You can delete all existing CHECK conditions, including column CHECK conditions, using ALTER TABLE DELETE CHECK, and then add in new CHECK conditions.

All CHECK conditions on a table, including CHECK conditions on all its columns and CHECK conditions inherited from user-defined data types, are removed using the ALTER TABLE statement with the DELETE CHECK clause, as follows:

ALTER TABLE table_name

DELETE CHECK

Deleting a column from a table does not delete CHECK conditions associated with the column that are held in the table constraint. If the constraints are not removed, any attempt to query data in the table will produce a column not found error message.

Table CHECK conditions fail only if a value of FALSE is returned. If a value of UNKNOWN is returned, the change is allowed.


Enforcing entity and referential integrity
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Enforcing entity and referential integrity

The relational structure of the database enables information within the database to be identified by the database engine, and ensures that relationships described in the database structure between tables are properly upheld by all the rows in each table.

 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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Enforcing entity and referential integrity

Enforcing entity integrity

When a new row in a table is created, or when a row is updated, SQL Anywhere 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 a new employee is added to the table, SQL Anywhere 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 columns identifies which line corresponding to the item. The two columns id and line_id, taken together, specify an item uniquely, and form the primary key.


If a client application breaches entity integrity
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Enforcing entity and referential integrity

If a client application breaches entity integrity

Entity integrity requires that each value of a primary key be unique within the table, and that there are no NULL values. If a client application attempts to insert or update a primary key value, and provides values that are not unique, entity integrity would be breached.

If SQL Anywhere detects an attempt to breach entity integrity, it does not add the new information to the database, and instead reports an error to the client application.

It is up to the application programmer to decide how to present this information to the user and enable the user to take appropriate action. The appropriate action in this case is usually just to provide a unique value for the primary key.


Primary keys enforce entity integrity
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Enforcing entity and referential integrity

Primary keys enforce entity integrity

Once the primary key for each table is specified, no further action is needed by client application developers or by the database administrator to maintain entity integrity.

The primary key for a table is defined by the table owner when the table is created. If the structure of a table is modified at a later date, the primary key may also be redefined.

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 command explicitly: the application generates the statement itself from the information you provide.

For information on creating primary keys, see "Creating primary and foreign 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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Enforcing entity and referential integrity

Enforcing referential integrity

A foreign key relates the information in one table (the foreign table) to information in another (referenced or primary) table. A particular column (or combination of columns) in a foreign table is designated as a foreign key to the primary table.

The entries in the foreign key must correspond to the primary key values of a row in the referenced table for the foreign key relationship to be valid. (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.

One of the items of information about each employee is the department ID of the department to which they belong. In the employee table, the department ID is called a foreign key for the department table; 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 were able to reference a column in the department table containing duplicate entries, there would be no way of knowing which of the rows in the department table is the appropriate reference.

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 where the employee's office is located. The database designer may wish to allow for an office location not being assigned at the time the employee is hired. In this case, the foreign key is optional and should allow the NULL value to indicate that it is optional when the office location is unknown or when the employee does not work out of an office. A foreign key that is not optional is called mandatory.


Foreign keys enforce referential integrity
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Enforcing entity and referential integrity

Foreign keys enforce referential integrity

Like primary keys, foreign keys are created using the CREATE TABLE statement or ALTER TABLE statement.

Once a foreign key has been created, SQL Anywhere ensures that the columns contain only values that are present as primary key values in the table associated with the foreign key.

For information on creating foreign keys, see "Creating primary and foreign keys".


Losing referential integrity
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Enforcing entity and referential integrity

Losing referential integrity

Referential integrity can be lost in the following ways:

♦	If a primary key value is updated or deleted, all those foreign keys referencing it would be left in an invalid state.

♦	If a new row is added to the foreign table, and a value is entered for the foreign key that has no corresponding primary key values, the database would be left in an invalid state.

SQL Anywhere provides protection against both types of integrity loss.


If a client application breaches referential integrity
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Enforcing entity and referential integrity

If a client application breaches referential integrity

If a client application updates or deletes a primary key value in a table, and if that primary key value is referenced by a foreign key elsewhere in the database, there is a danger of a breach of referential integrity.

Example

If the database engine 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 would exist.

While breaches of entity integrity are generally straightforward for SQL Anywhere to handle, simply by refusing to enter the data and returning an error message, these potential breaches of referential integrity are more complicated.

SQL Anywhere ensures that referential integrity is maintained, and provides four options for how this is to be done. These options are called referential integrity actions.


Referential integrity actions
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Enforcing entity and referential integrity

Referential integrity actions

The simplest way of maintaining referential integrity when a referenced primary key is updated or deleted is to disallow the update or delete.

It is often possible to take an 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 should be taken on foreign keys that reference a modified primary key.

Each of the available referential integrity actions may be specified separately for updates and deletes of the primary key:

♦	RESTRICT   Generate an error if an attempt is made to modify a referenced primary key value, and do not carry out the modification. This is the default referential integrity action.

♦	SET NULL   Set all foreign keys that reference the modified primary key to NULL.

♦	SET DEFAULT   Set all foreign keys that reference the modified primary key to the default clause for that column (as specified in the table definition).

♦	CASCADE   When used with ON UPDATE, update all foreign keys that reference the updated primary key to the new value of the primary key. When used with ON DELETE, delete all rows containing foreign keys that reference the deleted primary key.

Referential integrity actions are implemented using system triggers. The trigger is defined on the primary table, and is executed using the permissions of the owner of the primary table.


Referential integrity checking
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Enforcing entity and referential integrity

Referential integrity checking

For foreign keys defined to RESTRICT operations that would violate referential integrity, checks can be carried out at the time a statement is executed (the default) or only when a transaction is committed, by specifying the CHECK ON COMMIT clause.

Using a database option to control check time

SQL Anywhere operates in two different modes when a foreign key is defined to RESTRICT operations that would violate referential integrity, depending on the setting of the wait_for_commit database option. This option is overridden by the CHECK ON COMMIT clause.

Wait_for_commit = off

With the default setting (wait_for_commit = off — see "SET OPTION statement") a database operation that would leave the database inconsistent is not allowed to execute. For example, a DELETE operation of a department that has employees in it is not allowed. The statement:

DELETE FROM department

WHERE dept_id = 200

gives the error primary key for row in table 'department' is referenced in another table.

Wait_for_commit= on

If wait_for_commit is set to on, referential integrity is not checked until a commit is executed. If the database is in an inconsistent state, the commit is not allowed and an error is reported. In this mode, a department with employees could be deleted. However, the change could not be committed to the database until one of the following actions is taken:

♦	The employees belonging to that department are also deleted or reassigned.

♦	This search condition can also be used on a SELECT statement to select the rows that violate referential integrity.

♦	The dept_id row is inserted back into the department table.

♦	The transaction is rolled back to undo the DELETE operation.


Integrity rules in the system tables
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 18. Ensuring Data Integrity

Integrity rules in the system tables

All the information about integrity checks and rules in a database is held in the following system tables:

System table	Description
SYS.SYSTABLE	CHECK constraints are held in the view_def column of SYS.SYSTABLE. 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 respectively
SYS.SYSTRIGGER	Referential integrity actions are held in SYS.SYSTRIGGER. 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: a delete (D), insert (I), update (U), or update of column-list (C). 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 a description of the contents of each system table, see the chapter "SQL Anywhere System Tables". You can use Sybase Central or ISQL to browse these tables and views.


Using Transactions and Locks
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

About this chapter

This chapter describes transactions and how to use them in applications. It also describes the locking mechanisms available to assist concurrent usage of the database.

 An overview of transactions

 How locking works

 Isolation levels and consistency

 How SQL Anywhere handles locking conflicts

 Choosing an isolation level

 Savepoints within transactions

 Particular concurrency issues

 Transactions and portable computers


An overview of transactions
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

An overview of transactions

About transaction processing

SQL Anywhere supports transaction processing to ensure that logically related commands get executed as a unit, and to enable multiple applications to have access to a database.

When several users are working with the same information in a database at the same time (concurrently), their actions may interfere with each other to produce inconsistent and incorrect information. Transaction processing and row-level locking allow concurrent use while maintaining database consistency.

Who needs to know about transactions

Transaction processing is not a concern simply for developers of applications for multiuser database engines; developers working with single-user databases also have to be concerned with concurrency. Single-user SQL Anywhere databases may still have multiple applications connected to them, or may have 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 processing is fundamental to proper data recovery in case of system failures.

  For information about database backups and data recovery, see the chapter "Backup and Data Recovery".

Transactions are logical units of work

SQL statements are grouped into transactions. A transaction is a logical unit of work, meaning that the set of commands making up a transaction must be processed in its entirety, or not at all. From the user's point of view, a transaction is indivisible. Transactions are atomic.

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 issued (Database definition commands, such as ALTER, CREATE, COMMENT, or DROP all have the side effect of an automatic commit)

♦	A disconnection from a database (implicit rollback)

SQL Anywhere's transaction processing ensures that each transaction is processed in its entirety or not at all. Transaction processing is fundamental to ensuring that a database contains correct information. It addresses two distinct, yet related, problems: data recovery and database consistency in the face of concurrent usage.

Example

A transfer of funds from one account to another is an archetypal transaction. This transaction consists of two operations:

♦	Debit the account the money is coming from.

♦	Credit the account the money is going to.

If the transaction is completed properly both operations are recorded in the database. However, if something happens after the from account is debited to prevent the transaction being completed, then it is unacceptable to leave the debit in the database without recording the credit. Either both the debit and the credit must be processed, or neither. In case of failure, the debit needs to be undone, or rolled back.

 Transactions and data recovery

 Transactions and concurrency

 Three types of inconsistency

 Using locks to ensure consistency


Transactions and data recovery
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

An overview of transactions

Transactions and data recovery

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.

SQL Anywhere's transaction processing ensures that the contents of a transaction are processed securely, even in the event of system failures in the middle of a transaction. The mechanisms for data recovery are described in the chapter "Backup and Data Recovery". The remainder of this chapter is devoted to concurrency and consistency of transactions.


Transactions and concurrency
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

An overview of transactions

Transactions and concurrency

When several users are using a database at the same time they are said to be concurrent users. Even single-user databases need to be aware of concurrency problems, as several applications could be run at the same time on one machine, or a single application could have several active connections to the database at one time.

If several connections access the same information in a database at the same time, they could interfere with each other and produce inconsistencies in the database. Transaction processing helps to ensure databases remain consistent while allowing concurrent transactions.


Three types of inconsistency
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

An overview of transactions

Three types of inconsistency

There are three types of inconsistency that can occur during the execution of concurrent transactions:

♦	Dirty read   Transaction A modifies a row. Transaction B then reads that row before transaction A performs a COMMIT. If transaction A then performs a ROLLBACK, transaction B will have read a row that was never committed.

♦	Nonrepeatable 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.

♦	Phantom row   Transaction A reads a set of rows that satisfy some condition. Transaction B then executes an INSERT, or an UPDATE (that generates one or more rows that satisfy the condition used by transaction A) and then performs a COMMIT. Transaction A then repeats the initial read and obtains a different set of rows.


Using locks to ensure consistency
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

An overview of transactions

Using locks to ensure consistency

SQL Anywhere uses a locking scheme to ensure that concurrent transactions do not interfere with each other to produce inconsistencies.

Inconsistency in the information an application sees is tolerable in some cases. Therefore, we do not need to prohibit all forms of inconsistent behavior in all cases. For this reason, the client application developer is given some control over the level of consistency required in the information the application sees.

SQL Anywhere locking scheme

The SQL Anywhere locking scheme restricts access to the information that a particular transaction is working with to ensure that other transactions do not see information that may not be committed to the database, and do not alter information on which the transaction is relying. The locking scheme is discussed in detail later in this chapter.

The way SQL statements are grouped into transactions can have significant effects on data integrity and on system performance. If a transaction is too short, and does not contain an entire logical unit of work, then inconsistencies can be introduced into the database. If a transaction is too long, and contains several unrelated actions, then there is greater chance of a ROLLBACK unnecessarily undoing work that could have been committed quite safely into the database. Also, if transactions are too long, and lock large amounts of data, they can prevent other transactions from being processed and so reduce concurrency.

There are many factors determining the appropriate length of a transaction, depending on the type of application and the environment. Some guidelines are given towards the end of this chapter.


How locking works
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

How locking works

When a transaction is reading or writing a row in a database table, the database engine automatically locks the individual row (row level locking) to prevent other transactions from interfering with the data, or from obtaining unreliable data. 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.

All locks for a transaction are held until the transaction is complete (COMMIT or ROLLBACK), with a single exception noted below.

SQL Anywhere allows users to determine the extent to which transactions can operate concurrently by setting isolation levels. Isolation levels are discussed in the next section.

Types of locks

There are three distinct types of locks:

♦	read lock

♦	write lock

♦	phantom lock

Uses for locks

They have the following uses:

♦	Whenever a transaction inserts, updates, or deletes a row, a write lock is set. No other transaction can obtain a lock on the same row when a write lock is set. A write lock is an exclusive lock.

♦	A read lock can be set when a transaction reads a row. Several transactions can acquire read locks on the same row (a read lock is a nonexclusive lock). However, once a row has been read locked no other transaction may obtain a write lock on it.

♦	A phantom lock is a read lock that prevents phantom rows. Phantom 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.


Isolation levels and consistency
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

Isolation levels and consistency

The degree to which the operations in one transaction are visible to the operations in a concurrent transaction is defined by isolation level. SQL Anywhere has four different isolation levels that prevent some or all inconsistent behavior. The isolation level is a database option that can be different for each connection. Database options are changed by using the SET command; the default setting is isolation level 0. For a description of the SET statement syntax, see the chapter "Watcom-SQL Language Reference".

All isolation levels guarantee that each transaction will execute completely or not at all, and that no updates will be lost. SQL Anywhere therefore ensures recoverability at all times, regardless of the isolation level.

Isolation levels and dirty reads, nonrepeatable reads, and phantom rows

The isolation levels are different with respect to dirty reads, nonrepeatable reads, and phantom rows. An x means that the behavior is prevented, and a [image] means that the behavior may occur.

Isolation level	0	1	2	3
Dirty reads		x	x	x
Non-repeatable reads			x	x
Phantom rows				x
If your application is using cursors to perform retrievals and updates, there is an additional level of isolation called cursor stability. Cursor stability guarantees that any row that is the current position of a cursor will not be modified by another transaction until the cursor leaves the row. No row fetched through a cursor yields uncommitted data. SQL Anywhere automatically provides cursor stability at isolation levels 1, 2, and 3.

 Locks and isolation levels

 Changing the isolation level


Locks and isolation levels
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

Isolation levels and consistency

Locks and isolation levels

Write locks are employed at all isolation levels. This ensures that once data is modified by a transaction, no other transaction can modify it until the transaction is either committed or rolled back. As long as the transaction completes, there is no danger of its database update being interfered with by any other user.

Isolation level 0 (Read uncommitted)

The default setting for SQL Anywhere is isolation level 0. Read locks are not employed at this isolation level.

When all transactions are running at isolation level 0, the only time a locking conflict occurs is when one transaction attempts to update or delete a row that has been inserted or updated by a different transaction and not yet committed.

Isolation level 1 (Read committed)

The only distinction between levels 0 and 1 occurs when one transaction has a write lock on a row (because it is modifying the row) and a second transaction attempts to read the row.

At isolation level 0, the second transaction is allowed to read the row, at the risk that the read may be dirty. At isolation level 1, the second transaction checks to see if there is a write lock on the row before reading it, and is not allowed to read it if a write lock is in place.

At isolation level 1, cursor stability is achieved by putting a read lock on the current row of a cursor. This read lock is removed when the cursor is moved. This is the only type of lock that does not persist until the end of a transaction.

Isolation level 2 (Repeatable read)

Read locks that persist until the end of a transaction are introduced at isolation level 2. Level 2 guarantees that there will be no non-repeatable reads. If an application once reads a row, that row will be available to be read again, and will give the same result.

No guarantee is given that the row can be updated, however, as another transaction may also have a read lock on the row.

Isolation level 3 (Serializable)

Isolation level 3 is the most secure level, and is also the one at which concurrency is most affected.

At isolation level 3 a phantom lock is employed to prevent phantom rows. If your application looks up data in tables without using an index, concurrency can suffer considerably under isolation level 3.


Changing the isolation level
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

Isolation levels and consistency

Changing the isolation level

SQL Anywhere allows you to change isolation levels at any time, including within a transaction, using the SET OPTION statement.

For more information, see "SET OPTION statement".

When the ISOLATION_LEVEL option is changed 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

This may be useful, for example, when just one table or group of tables involved in a transaction requires serialized access, and so a high isolation level.


How SQL Anywhere handles locking conflicts
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

How SQL Anywhere handles locking conflicts

When a transaction attempts to acquire a lock on a row, but is forbidden by a lock held by another transaction, a locking conflict arises and the transaction attempting to acquire the lock is blocked. The section "Locking conflicts and transaction blocking" describes how SQL Anywhere handles transaction blocking.

"Transaction blocking and deadlock" describes how SQL Anywhere handles a deadlock when transactions cannot become unblocked.

 Locking conflicts and transaction blocking

 Transaction blocking and deadlock


Locking conflicts and transaction blocking
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

How SQL Anywhere handles locking conflicts

Locking conflicts and transaction blocking

When a locking conflict occurs, one transaction must wait for another transaction to complete. A transaction becomes blocked on another transaction. If two transactions simultaneously have a read lock on a row, the behavior when one of them attempts to modify that row (acquire a write lock) depends on the database setting BLOCKING.

♦	If BLOCKING is ON (the default setting), then the transaction that attempts to write is blocked until the other transaction releases its read lock. At that time, the write goes through.

♦	If BLOCKING has been set to OFF, then the transaction that attempts to write receives an error.

Blocking is more likely to occur with higher isolation levels because more locking and more checking is done. Higher isolation levels provide less concurrency.

For information about the BLOCKING option, see "SET OPTION statement".


Transaction blocking and deadlock
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

How SQL Anywhere handles locking conflicts

Transaction blocking and deadlock

Transaction blocking can lead to deadlock, where a set of transactions get into 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 (see the THREAD_COUNT option in "SET OPTION statement") 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.

SQL Anywhere automatically cancels the last transaction that became blocked (eliminating the deadlock situation), and returns an error to that transaction indicating which form of deadlock occurred.


Choosing an isolation level
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

Choosing an isolation level

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.

 Typical level 0 transactions

 Transactions for which no updates are lost

 Serializable transactions


Typical level 0 transactions
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

Choosing an isolation level

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. An 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 was required for such an application, it could hold read locks on large amounts of data, not allowing other applications write access to it.


Transactions for which no updates are lost
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

Choosing an isolation level

Transactions for which no updates are lost

Some applications require that no updates be lost. The following example typifies the lost update problem.

Example

Consider a sequence of instructions which could occur when two people put money into the same account at about the same time.

The initial account balance is $1000, and two people (Alex and Ben, say) are about to deposit money into it. Alex will deposit $2000, while Ben will deposit $100. We'll call Alex's transaction is transaction A and Ben's transaction is transaction B.

♦	A reads the account balance and finds it to be $1000.

♦	B reads the account balance and finds it to be $1000.

♦	A adds $2000 to the present balance of $1000 to calculate the new account balance. It then updates the account balance to reflect Alex's deposit. It writes a new balance of $3000 into the database.

♦	B adds $100 to the present account balance, which it has read as $1000, to calculate the new account balance. It then updates the account balance to reflect Ben's deposit, and writes a balance of $1100 into the database.

♦	The final balance recorded after the two deposits is $1100.

While both transactions are perfectly correct in themselves, the interaction between the two creates an invalid result in the database, and Alex's update was lost.

Isolation levels that prevent lost updates

SQL Anywhere's locking mechanism prevents lost updates at isolation level 2 and 3. If your application is using cursors, then cursor stability (achieved at isolation level 1) guarantees no lost updates.


Serializable transactions
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

Choosing an isolation level

Serializable transactions

Some applications require serializable transactions due to the nature of the application. Isolation level 3 enforces serializability.

When transactions are serializable, they behave as if they were run one after another even if they were actually run concurrently. For example, banking software must prevent two machines from checking a balance and withdrawing the full amount from the account at the same time.

Transactions of this type should read few or no rows and last at most a few seconds, so that concurrency is not likely to be a problem. Applications that involve a high volume of small transactions can use isolation level 3 without sacrificing concurrency.


Savepoints within transactions
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

Savepoints within transactions

Within a transaction, SQL Anywhere supports savepoints. Before Watcom SQL 4.0, a savepoint was referred to as a subtransaction.

A SAVEPOINT statement defines a point in a transaction where all changes after the point can be undone by a ROLLBACK TO SAVEPOINT statement. Once a RELEASE SAVEPOINT statement has been executed, the savepoint can no longer be used.

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

Savepoints can be named and they can be nested. By using named, nested savepoints, you can have many active savepoints within a transaction. Changes between a SAVEPOINT and a RELEASE SAVEPOINT can still 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 make use of the rollback log. They cannot be used in bulk operations mode. There is very little additional overhead in using savepoints.


Particular concurrency issues
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

Particular concurrency issues

This section discusses the following particular concurrency issues:

♦	Primary key generation

♦	Data definition statements and concurrency

♦	Coordinating transactions with multiple database engines

 Primary key generation

 Data definition statements and concurrency

 Coordinating transactions with multiple database engines


Primary key generation
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

Particular concurrency issues

Primary key generation

Many applications generate primary key values automatically.

Example

For example, invoice numbers could be obtained by adding 1 to the previous invoice number. This 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:

♦	Use a different range of invoice numbers for each person that adds new invoices.

♦	This could be done by having a table with two 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).

♦	Have a table with two columns (table name and last key value).

♦	There would be one row in this table for the last invoice number used. Each time a user adds an invoice, establish a new connection, increment the number in the table, and commit. 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.

♦	Probably the best solution is to 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.


Data definition statements and concurrency
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

Particular concurrency issues

Data definition statements and concurrency

The CREATE INDEX statement, ALTER TABLE statement, and DROP statement are prevented whenever the statement affects a table that is currently being used by another connection. These 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 engine, but do not affect existing outstanding statements.

GRANT and REVOKE for a user are not allowed if that user is connected to the database.


Coordinating transactions with multiple database engines
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

Particular concurrency issues

Coordinating transactions with multiple database engines

Two-phase commit is a mechanism of coordinating transactions between multiple servers. It is a primary component of most distributed database systems. Most applications do not need to use two-phase commit.

The first phase of a two-phase commit asks the database engine to prepare to commit and report any errors that would occur on a commit. This phase is accomplished with the PREPARE TO COMMIT statement. The second phase actually performs the commit operation using the COMMIT statement.

If you want to coordinate transactions with multiple servers, you can issue the PREPARE TO COMMIT statement to each server. If one of them fails, you can deal with the error or rollback all transactions. If all of the first phase commits are successful, you can commit each transaction knowing that there won't be any errors (except environment errors such as a network connection going down or one of the servers going off line).


Transactions and portable computers
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

Transactions and portable computers

Some of the 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.

Clearly, they cannot update the database server while they are not connected to the network. They can, however, take a copy of the database file and make updates to the copy using the SQL Anywhere server Standalone database engine running on the portable computer. Later, on returning to the office, the transaction log can be translated into a command file and applied to the database server.

This type of process is fully automated by the new SQL Remote replication system, described in chapters "Introduction to SQL Remote Replication" and "SQL Remote Administration".

Required software—You must purchase a copy of SQL Anywhere Standalone and SQL Remote for each machine on which you wish to deploy a client application running on the SQL Anywhere Standalone database engine.

 Applying updates from a portable computer

 Distributing applications that do not require server updates

 Working with large databases on portable computers


Applying updates from a portable computer
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

Transactions and portable computers

Applying updates from a portable computer

There are potential problems with applying translated transaction logs. When machines are connected to the network, locking prevents conflicting updates to records in the database. When a user makes changes to a copied database, there is no such protection. Consider what happens when two users update the same record, or one user deletes a record that another user updates. You can design applications to avoid this sort of problem by having each user update an isolated subset of the data, but you need to be aware of the possibility.

One solution is to use the -v command line switch when starting the database engine on the portable computer. This causes the engine to record the previous values of every column whenever a row of the database is updated. When the transaction log is translated (using DBTRAN) every UPDATE will have a WHERE clause specifying the value of every column in the row. The row will not be updated if any value has been changed by another user. ISQL will display a message if an UPDATE does not affect any rows, indicating that the particular database row has already been updated or deleted by someone else. When this happens, your update procedure will need manual intervention to resolve the potential conflict.

SQL Remote has full conflict detection capabilities and the ability to resolve conflicts through conflict triggers.


Distributing applications that do not require server updates
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

Transactions and portable computers

Distributing applications that do not require server updates

If you want to deploy applications that work on information taken from a database file, but which do not require applying updates to a multiuser database, you can install the SQL Anywhere Desktop Runtime System on each computer.

The runtime database engine supports the full range of data manipulation language commands, such as INSERT, DELETE and UPDATE, but does not employ a transaction log. Consequently, updates made on the local database cannot be applied to a multiuser database.

Required software— To use the single-user runtime database engine on an unlimited number of machines, you need to have purchased the SQL Anywhere Desktop Runtime System.


Working with large databases on portable computers
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 19. Using Transactions and Locks

Transactions and portable computers

Working with large databases on portable computers

With large database files, it may help to use DBSHRINK to compress the database before making a copy. In this case you will need to use a write file with the copied database (see DBWRITE).

You could also use a subset of the large database by creating an extraction procedure that builds a database that contains only the data needed by one person. As long as the table names and column names are identical, translated transaction logs from the smaller database can be applied to the main database.


Using Procedures, Triggers, and Batches
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. 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 procedure 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.

 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

 Some hints for writing procedures

 Statements allowed in batches

 Calling external libraries from stored procedures


Procedure and trigger overview
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Procedure and trigger overview

Procedures and triggers store procedural SQL statements in a database for use by all applications.

Procedures and triggers 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. Procedures can also return result sets to the caller. Procedures can call other procedures and fire triggers.

Triggers are associated with specific database tables. They are invoked automatically (fired) whenever rows of the associated table are inserted, updated or deleted. Triggers do not have parameters and cannot be invoked by a CALL statement. Triggers can call procedures and fire other triggers.

User-defined functions are one kind of stored procedure that returns a single value to the calling environment. User-defined functions do not modify parameters passed to them. They broaden the scope of functions available to queries and other SQL statements.


Benefits of procedures and triggers
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Benefits of procedures and triggers

Procedures and triggers are defined in the database, separate from any one database application. This separation provides a number of advantages.

Standardization

Procedures and triggers allow standardization of any actions that are performed by more than one application program. The action is coded once and stored in the database. The applications need only CALL the procedure or fire the trigger to achieve the desired result. If the implementation of the action evolves over time, any changes are made in only one place, and all applications that use the action automatically acquire the new functionality.

Efficiency

When used in a database implemented on a network server, procedures and triggers are executed on the database server machine. They can access the data in the database without requiring network communication. This means that 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 a procedure or trigger is created, it is checked for correct syntax and then stored in the system tables. The first time it is required by any application, it is retrieved from the system tables and compiled into the virtual memory of the database engine, and executed from there. Subsequent executions of the same procedure or trigger will result in immediate execution, since the compiled copy is retained. A procedure or trigger can be used concurrently by several applications and recursively by one application. Only one copy is compiled and kept in virtual memory.

Security

Procedures, including user-defined functions, execute with the permissions of the procedure owner but can be called by any user that has been granted permission to do so.

Triggers execute under the table permissions of the owner of the associated table but are fired by any user with permission to insert, update or delete rows in the table. This means that a procedure or trigger can (and usually does) have different permissions than the user ID that invoked it. Procedures and triggers provide security by allowing users limited access to data in tables that they cannot directly examine or modify.


Introduction to procedures
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Introduction to procedures

In order to use procedures you need to understand how to do the following:

♦	Create procedures

♦	Drop, or remove, procedures

♦	Call procedures from a database application

♦	Control who has permission to use procedures

This section discusses each of these aspects of using procedures, and also describes some of the different uses of procedures.

 Creating procedures

 Calling procedures

 Dropping procedures

 Permissions to execute procedures

 Returning procedure results in parameters

 Returning procedure results in result sets


Creating procedures
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Introduction to procedures

Creating procedures

Procedures are created using the CREATE PROCEDURE statement. You must have RESOURCE authority in order to create a procedure.

The following simple example creates a procedure that carries out an insert into the department table of the sample database, creating a new department.

You can create the example procedure new_dept by connecting to the sample database from the ISQL utility as user ID DBA, using password SQL, and typing the statement in the command window.

If you are using a tool other than ISQL or Sybase Central, you may need to change the command delimiter away from the semicolon before entering the CREATE PROCEDURE statement.

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

  For a complete description of the CREATE PROCEDURE syntax, see "CREATE PROCEDURE statement".

The body of a procedure is a compound statement (see "Using compound statements"). 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 are marked as one of IN, OUT, or INOUT. All parameters to the new_dept procedure are IN parameters, as they are not changed by the procedure.


Calling procedures
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Introduction to procedures

Calling procedures

A procedure is invoked with a CALL statement (see "CALL statement".) Procedures can be called by an application program or they can be called by other procedures and triggers.

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.

 To list all departments:

1	Type the following:

SELECT *

FROM department

dept_id	dept_name	dept_head_id
100	R & D	501
200	Sales	902
300	Finance	1293
400	Marketing	1576
500	Shipping	703
210	Eastern Sales	902
The new_dept procedure can be called by any user who has been granted EXECUTE permission for the procedure, even if they have no permissions on the department table.


Dropping procedures
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Introduction to procedures

Dropping procedures

Once a procedure is created, it remains in the database until it is explicitly removed. Only the owner of the procedure or a user with DBA authority can drop the procedure from the database.

The following statement removes the procedure new_dept from the database:

DROP PROCEDURE new_dept


Permissions to execute procedures
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Introduction to procedures

Permissions to execute procedures

A procedure is owned by the user who created it and that user can execute it without permission. Permission to execute it can be granted to other users using the GRANT EXECUTE command.

For example, the owner of the procedure new_dept could allow another_user to execute new_dept with the statement:

GRANT EXECUTE ON new_dept TO another_user

The following statement revokes permission to execute the procedure:

REVOKE EXECUTE ON new_dept FROM another_user

  For more information on managing user permissions on procedures, see "Granting permissions on procedures".


Returning procedure results in parameters
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Introduction to procedures

Returning procedure results in parameters

Procedures can return results to the calling environment in one of the following ways:

♦	Individual values are returned as OUT or INOUT parameters to the procedure

♦	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

DECIMAL(20,3) )

BEGIN

SELECT AVG( salary ) INTO avgsal FROM employee;

END

To run this procedure and display its output from the ISQL utility, carry out the following steps:

♦	Connect to the sample database from the ISQL utility as user ID DBA using password SQL.

♦	Create the procedure.

♦	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)

♦	Call the procedure, using the created variable to hold the result: CALL AverageSalary(Average) The ISQL statistics window displays the message "Procedure completed" if the procedure was created and run properly.

♦	Look at the value of the output variable Average. The ISQL data window displays the value 49988.623 for this variable; the average employee salary.


Returning procedure results in result sets
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Introduction to procedures

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 called from ISQL, 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 within ISQL you can CALL it, specifying one of the departments of the company. The results are displayed in the ISQL data window. For example:

 To list the salaries of employees in the R & D department (department ID 100):

1	Type the following:

CALL SalaryList (100)

Employee ID	Salary
102	45700.000
105	62000.000
160	57490.000
243	72995.000
247	48023.690
To execute a CALL of a procedure that returns a result set, ISQL opens a cursor.

The cursor is left open after the CALL in case a second result set is returned. The ISQL statistics window displays the plan of the SELECT query in the procedure and then displays the line:

Procedure is executing. Use RESUME to continue.

You need to execute the RESUME statement from the ISQL command window before you can, for example, DROP the procedure. Alternatively, the ISQL CLEAR statement clears the window.

  For more information about using cursors in procedures, see "Using cursors in procedures and triggers".


Introduction to user-defined functions
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Introduction to user-defined functions

User-defined functions are a class of procedures that return a single value to the calling environment. This section introduces creating, using, and dropping user-defined functions

 Creating user-defined functions

 Calling user-defined functions

 Dropping user-defined functions

 Permissions to execute user-defined functions


Creating user-defined functions
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Introduction to user-defined functions

Creating user-defined functions

User-defined functions are created using the CREATE FUNCTION statement. You must have RESOURCE authority in order to create a user-defined function.

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.

You can create the example function fullname by connecting to the sample database from the ISQL utility as user ID DBA, using password SQL, and typing the statement in the command window.

If you are using a tool other than ISQL or Sybase Central, you may need to change the command delimiter away from the semicolon before entering the CREATE FUNCTION statement.

CREATE FUNCTION fullname (firstname CHAR(30),

   lastname CHAR(30))

RETURNS CHAR(61)

BEGIN

   DECLARE name CHAR(61);

   SET name = firstname || ' ' || lastname;

   RETURN ( name );

END

For a complete description of the CREATE FUNCTION syntax, 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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Introduction to user-defined functions

Calling user-defined functions

A user-defined function can be used, subject to permissions, in any place that a built-in non-aggregate function is used.

The following statement in ISQL displays 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)

Phillip Chin

The following statement in ISQL displays a full name from a supplied first and last name:

SELECT fullname ('Jane', 'Smith');

fullname ('Jane','Smith')

Jane Smith

The fullname function can be used by any user who has been granted EXECUTE permission for the function.


Dropping user-defined functions
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Introduction to user-defined functions

Dropping user-defined functions

Once a user-defined function is created, it remains in the database until it is explicitly removed. 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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Introduction to user-defined functions

Permissions to execute user-defined functions

A user-defined function is owned by the user who created it and that user can execute it without permission. Permission to execute it can be granted to other users using 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 permission 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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Introduction to triggers

Triggers are used whenever referential integrity and other declarative constraints are not sufficient (see the chapter "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.

Triggers can be defined on one or more of the following triggering actions:

Action	Description
INSERT	The trigger is invoked whenever a new row is inserted into the table associated with the trigger
DELETE	The trigger is invoked whenever a row of the associated table is deleted.
UPDATE	The trigger is invoked whenever a row of the associated table is updated.
UPDATE OF column-list	The trigger is invoked whenever a row of the associated table is updated such that a column in the column-list has been modified
Triggers can be defined as row-level triggers or statement-level triggers. Row-level triggers can execute BEFORE or AFTER each row modified by the triggering insert, update, or delete operation is changed. Statement-level triggers execute after the entire operation is performed.

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) are undone.

 Creating triggers

 Executing triggers

 Dropping triggers

 Trigger execution permissions


Creating triggers
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Introduction to triggers

Creating triggers

You create triggers using the CREATE TRIGGER statement. You must have RESOURCE authority in order to create a trigger and you must have ALTER permissions on the table associated with the trigger. For information about ALTER permissions, see "Granting permissions on tables and views". For information about RESOURCE permissions, see "Granting DBA and resource authority".

The body of a trigger consists of a compound statement (see "Using compound statements"): a set of semicolon-delimited SQL statements bracketed by a BEGIN and an END statement.

COMMIT and ROLLBACK and some ROLLBACK TO SAVEPOINT statements are not permitted within a trigger (see "Transactions and savepoints in procedures and triggers").

A row-level INSERT trigger example

The following trigger is an example of a row-level INSERT trigger. It checks that the birthdate 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, 1994' THEN

      SIGNAL err_user_error;

   END IF;

END

This trigger is fired just 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, 1994.

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 is fired once for each new row. If the trigger fails for any of the rows, all effects of the INSERT statement are rolled back.

You can specify that the trigger fire 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.

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 fire after the row is deleted rather than before, by changing the first line of the example to:

CREATE TRIGGER mytrigger BEFORE DELETE ON employee

The REFERENCING OLD clause is independent of the timing (BEFORE or AFTER) of the trigger.

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. Columns in the new row are referred to with the table alias table_after_update and columns in the old row are referred to with the table alias table_before_update.

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.


Executing triggers
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Introduction to triggers

Executing triggers

Triggers are executed automatically whenever an INSERT, UPDATE, or DELETE operation is performed on the table named in the trigger. A row-level trigger is fired once for each row that is affected, while a statement-level trigger is fired once for the entire statement.

When an INSERT, UPDATE, or DELETE fires a trigger, the order of operation is as follows:

♦	Any BEFORE triggers are fired.

♦	Any referential actions are performed.

♦	The operation itself is performed.

♦	Any AFTER triggers are fired.

If any of the steps encounters an error that is 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.


Dropping triggers
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Introduction to triggers

Dropping triggers

Once a trigger is created, it remains in the database until it is explicitly removed. You must have ALTER permissions on the table associated with the trigger.

The following statement removes the trigger mytrigger from the database:

DROP TRIGGER mytrigger


Trigger execution permissions
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Introduction to triggers

Trigger execution permissions

You cannot grant permissions to execute a trigger, as triggers are not executed by users: they are fired by the database engine 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 that caused the trigger to fire, and not the permissions of the user that 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 is fired.

Also, user_1 must have permission to carry out the operations specified in the trigger.


Introduction to batches
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Introduction to batches

A simple batch consists of a set of SQL statements, separated by semicolons. For example, the following set of statements form a batch:

Create an Eastern Sales department, and transfer all sales reps from Massachusetts to that department.

INSERT

INTO department ( dept_id, dept_name )

VALUES ( 220, 'Eastern Sales' ) ;

UPDATE employee

SET dept_id = 220

WHERE dept_id = 200

AND state = 'MA' ;

COMMIT ;

You can include this set of statements in an application and execute them together.

ISQL and batches—A list of semicolon-separated statements, such as the above, is parsed by ISQL prior to sending to the database engine. In this case, ISQL sends each statement individually to the engine, not as a batch. Unless you have such parsing code in your application, the statements would be sent and treated as a batch. Other batches described below are sent by ISQL as a batch, not as a set of individual statements. Putting a BEGIN and END around a set of statements causes ISQL 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:

BEGIN

   IF NOT EXISTS (

      SELECT * FROM SYSTABLE

      WHERE table_name = 't1' ) THEN

      CREATE TABLE t1 (

            firstcol INT PRIMARY KEY,

            secondcol CHAR( 30 )

      ) ;

   ELSE

      MESSAGE 'Table t1 already exists' ;

   END IF

END

If you run this batch twice from ISQL, it creates the table the first time you run it, and prints the message on the server or engine message window the next time you run it.


Control statements
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

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. The following is a list of control statements available.

Control statement	Syntax
Compound statements	BEGIN [ ATOMIC ]    statement-list  END
Conditional execution: IF	IF condition THEN    statement-list ELSEIF condition THEN    statement-list ELSE    statement-list END IF
Conditional execution: CASE	CASE expression  WHEN value THEN    statement-list WHEN value THEN     statement-list  ELSE     statement-list  END CASE
Repetition: WHILE, LOOP	WHILE condition LOOP     statement-list END LOOP
Repetition: FOR cursor loop	FOR     statement-list  END FOR
Break: LEAVE	LEAVE label
CALL	CALL procname( arg, ... )
For complete descriptions of each, see the entries in "Watcom-SQL Language Reference".

 Using compound statements

 Declarations in compound statements

 Atomic compound statements


Using compound statements
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Control statements

Using compound statements

A compound statement starts with the keyword BEGIN and ends 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. SQL statements within a compound statement should be delimited with semicolons.


Declarations in compound statements
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Control statements

Declarations in compound statements

Local declarations in a compound statement immediately follow the BEGIN keyword. These local declarations exist only within the compound statement. The following may be declared within a compound statement:

♦	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 within the compound statement.

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.


Atomic compound statements
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Control statements

Atomic compound statements

An atomic statement is a statement that is 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 are undone. The UPDATE statement is atomic.

All noncompound SQL statements are atomic. A compound statement can be made 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.

COMMIT and ROLLBACK and some ROLLBACK TO SAVEPOINT statements are not permitted 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 is when an error occurs, and is handled by an exception handler within the compound statement.

  For more information, see "Using exception handlers in procedures and triggers".


The structure of procedures and triggers
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

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. The statements must be delimited by semicolons.

The SQL statements that can occur in procedures and triggers are described in "SQL statements allowed in procedures and triggers".

Procedures and triggers can contain control statements, which are described in "Control statements".

 SQL statements allowed in procedures and triggers

 Declaring procedure parameters

 Passing parameters to procedures

 Passing parameters to functions


SQL statements allowed in procedures and triggers
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

The structure of procedures and triggers

SQL statements allowed in procedures and triggers

Many SQL statements are allowed 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 are not allowed within procedures and triggers. These include the following:

♦	CONNECT statement

♦	DISCONNECT statement.

COMMIT, ROLLBACK and SAVEPOINT statements are allowed within procedures and triggers with certain restrictions (see "Transactions and savepoints in procedures and triggers").

For details, see the Usage for each SQL statement in the chapter "Watcom-SQL Language Reference".


Declaring procedure parameters
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

The structure of procedures and triggers

Declaring procedure parameters

Procedure parameters, or arguments, are specified 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 be one of the types supported by SQL Anywhere (see "SQL Anywhere Data Types"), and must be prefixed with one of the keywords IN, OUT or INOUT. 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.

Default values can be assigned 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 causes the DEFAULT NULL to be assigned, and the procedure RETURNs instead of executing the query.

CALL customer_products();


Passing parameters to procedures
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

The structure of procedures and triggers

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 )

and so on.


Passing parameters to functions
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

The structure of procedures and triggers

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:

 To list the names of all employees:

1	Type the following:

SELECT fullname(emp_fname, emp_lname) AS Name

FROM employee

Name

Fran Whitney

Matthew Cobb

Philip Chin

Julie Jordan

Robert Breault

...

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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Returning results from procedures

Procedures can return results that are a single row of data, or multiple rows. In the former case, results can be passed back as arguments to the procedure, in the latter case, results 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 information about returning a single row, see "Returning results as procedure parameters". For information about returning multiple rows, see "Returning result sets from procedures".

 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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Returning results from procedures

Returning a value using the RETURN statement

A single value can be returned to the calling environment using the RETURN statement, which causes 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, an extension of the CALL statement is used:

CREATE VARIABLE returnval INTEGER ;

returnval = CALL myproc() ;


Returning results as procedure parameters
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Returning results from procedures

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 in one of the following ways:

♦	The parameter can be assigned a value using the SET statement.

♦	The parameter can be assigned a value using a SELECT statement with an INTO clause.

Using the SET statement

The following somewhat artificial procedure returns a value in an OUT parameter that is 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 is achieved by 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 is executed, the database engine retrieves the results of the select statement and places the results in the variables. If the query results contain more than one row, the database engine returns an error. For queries returning more than one row, cursors must be used. 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 is returned.

The following procedure returns the results of a single-row SELECT statement in the procedure parameters.

 To return the number of orders placed by a given customer:

1	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

This procedure can be tested in ISQL 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 that is passed in to the procedure.

♦	The Orders parameter is declared as an OUT parameter. It holds the value of the orders variable that is returned to the calling environment.

♦	No DECLARE statement is required 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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Returning results from procedures

Returning result sets from procedures

If a procedure returns more than one row of results to the calling environment, it does so using result sets.

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 is not followed by a command delimiter.

♦	The names of the SELECT list items do not need to match those of the RESULT list.

♦	When testing this procedure, ISQL opens a cursor to handle the results. The cursor is left open following the SELECT statement, in case the procedure returns more than one result set. You should type RESUME to complete the procedure and close the cursor.


Returning multiple result sets from procedures
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Returning results from procedures

Returning multiple result sets from procedures

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 ISQL, enter the statement CALL ListPeople (); You must enter a RESUME statement after each of the three result sets is displayed in the ISQL data window to continue, and then complete, the procedure.

♦	A command delimiter is required after the first two SELECT statements. It is optional after the final statement in a statement list.


Returning variable result sets from procedures
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Returning results from procedures

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 are not using this feature of variable result sets, it is recommended that you employ 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 information about the DESCRIBE statement, see "DESCRIBE statement".

♦	ODBC   Variable result set procedures can be used by ODBC applications. The proper description of the variable result sets is carried out by the SQL Anywhere ODBC driver.

♦	Open Client applications   Variable result set procedures can be used by Open Client applications using the Open Server Gateway. The proper description of the variable result sets is carried out by the Open Server Gateway.

♦	ISQL   ISQL does not support calling of variable result set procedures, and so cannot be used for testing this feature.


Using cursors in procedures and triggers
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Using cursors in procedures and triggers

Cursors are used to retrieve rows one at a time from a query or stored procedure that has 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

 Using cursors on SELECT statements in procedures


Cursor management overview
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Using cursors in procedures and triggers

Cursor management overview

Managing a cursor is similar to managing a file in a programming language. The following steps are used to manage cursors:

♦	Declare a cursor for a particular select statement or procedure using the DECLARE statement.

♦	Open the cursor using the OPEN statement.

♦	Use the FETCH statement to retrieve results one row at a time from the cursor.

♦	Records are usually fetched until the row not found warning is returned, signaling the end of the result set.

♦	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 that are opened using the WITH HOLD clause will be kept open for subsequent transactions until they are explicitly closed.

Cursor positioning

A cursor can be positioned at one of three places:

♦	On a row

♦	Before the first row

♦	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"). It can be positioned to an absolute position either from the start or from the end of the query results (using FETCH ABSOLUTE, FETCH FIRST, or FETCH LAST). It can also be moved relative to the current cursor position (using FETCH RELATIVE, FETCH PRIOR, or FETCH NEXT). The NEXT keyword is the default qualifier for the FETCH statement.

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 will be returned.

Cursor positioning problems—Inserts and some updates to DYNAMIC SCROLL cursors can cause problems with cursor positioning. The database engine will 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 will not appear at all until the cursor is closed and opened again.
With SQL Anywhere, this occurs if a temporary table had to be created to open the cursor (see "Temporary tables used 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). Using STATIC SCROLL cursors alleviates these problems but is more expensive.


Using cursors on SELECT statements in procedures
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Using cursors in procedures and triggers

Using cursors on SELECT statements in procedures

The following procedure uses a cursor on a SELECT statement. It illustrates several features of the stored procedure language. It is based on the same query used in the ListCustomerValue procedure described in "Returning result sets from procedures".

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 is used to detect when a loop over the results of a query has completed.

  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 is opened.

♦	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 is closed at the end of the procedure.

The LOOP construct in the TopCompanyValue procedure is a standard form, exiting after the last row is processed. 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

   CompanyLoop:

   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 CompanyLoop;

END


Errors and warnings in procedures and triggers
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Errors and warnings in procedures and triggers

After an application program executes a SQL statement, it can examine a return code. This return code indicates whether the statement executed successfully or failed and gives the reason for the failure. The same mechanism can be used to indicate the success or failure of a CALL statement to a procedure.

SQL Anywhere supports the SQLCODE and SQLSTATE status descriptions. For full descriptions of SQLCODE and SQLSTATE error and warning values and their meanings, see the chapter "SQL Anywhere Database Error Messages". Whenever a SQL statement is executed, a value is placed 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.

Possible values for the SQLSTATE and SQLCODE variables are listed in the chapter "SQL Anywhere Database Error Messages".

 Default error handling in procedures and triggers

 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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Errors and warnings in procedures and triggers

Default error handling in procedures and triggers

This section describes how SQL Anywhere handles errors that occur during a procedure execution, if you have no error handling built in to the procedure.

If you want to have different behavior from that described in this section, 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 is included in the CREATE PROCEDURE statement, the procedure carries on executing after an error, resuming at the statement following the one causing the error.

Default error handling

Generally, if a SQL statement in a procedure or trigger fails, the procedure or trigger terminates execution and control is returned 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.';

   CALL InnerProc();

   MESSAGE 'SQLSTATE set to ',

      SQLSTATE,' in OuterProc.'

END

CREATE PROCEDURE InnerProc()

   BEGIN

      DECLARE column_not_found

         EXCEPTION FOR SQLSTATE '52003';

      MESSAGE 'Hello from InnerProc.';

      SIGNAL column_not_found;

   MESSAGE 'SQLSTATE set to ',

      SQLSTATE, ' in InnerProc.';

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 database engine. The DECLARE statement does not take any other action.

♦	The MESSAGE statement sends a message to the database engine or server message window.

♦	The SIGNAL statement generates an error condition from within the InnerProc procedure.

The following statement executes the OuterProc procedure:

CALL OuterProc();

The message window of the database engine then displays the following:

Hello from OuterProc.

Hello from InnerProc.

No statements following the SIGNAL statement in InnerProc are executed: InnerProc immediately passes control back to the calling environment, which in this case is the procedure OuterProc. The error condition is returned to the calling environment to be handled there. For example, the ISQL utility 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 ISQL by typing the following statement:

SELECT TRACEBACK(*)

Error handling with ON EXCEPTION RESUME

If the ON EXCEPTION RESUME clause is included in the CREATE PROCEDURE statement, the procedure does not return control to the calling environment when an error occurs. Instead, it continues executing, resuming at the statement after the one causing the error.

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

   MESSAGE 'Hello from OuterProc.';

   CALL InnerProc();

   MESSAGE 'SQLSTATE set to ',

      SQLSTATE,' in OuterProc.';

END;

CREATE PROCEDURE InnerProc()

ON EXCEPTION RESUME

BEGIN

   DECLARE column_not_found

      EXCEPTION FOR SQLSTATE '52003';

   MESSAGE 'Hello from InnerProc.';

   SIGNAL column_not_found;

   MESSAGE 'SQLSTATE set to ',

      SQLSTATE, ' in InnerProc.';

END

The following statement executes the OuterProc procedure:

CALL OuterProc();

The message window of the database engine then displays the following:

Hello from OuterProc.

Hello from InnerProc.

SQLSTATE set to 52003 in InnerProc.

SQLSTATE set to 52003 in OuterProc.


Default handling of warnings in procedures and triggers
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Errors and warnings in procedures and triggers

Default handling of warnings in procedures and triggers

Warnings are handled differently from errors. While the default action for errors is to set a value for the SQLSTATE and SQLCODE variables, and return control to the calling environment, the default action for warnings is to set the SQLSTATE and SQLCODE values and continue execution of the procedure.

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.';

   CALL InnerProc();

   MESSAGE 'SQLSTATE set to ',

      SQLSTATE,' in OuterProc.';

END

CREATE PROCEDURE InnerProc()

BEGIN

   DECLARE row_not_found

      EXCEPTION FOR SQLSTATE '02000';

   MESSAGE 'Hello from InnerProc.';

   SIGNAL row_not_found;

   MESSAGE 'SQLSTATE set to ',

   SQLSTATE, ' in InnerProc.';

END

The following statement executes the OuterProc procedure:

CALL OuterProc();

The message window of the database engine then displays the following:

Hello from OuterProc.

Hello from InnerProc.

SQLSTATE set to 02000 in InnerProc.

SQLSTATE set to 02000 in OuterProc.

The procedures both continued executing after the warning was generated, with SQLSTATE set to the value set by the warning (02000).


Using exception handlers in procedures and triggers
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Errors and warnings in procedures and triggers

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.

An exception handler is defined with the EXCEPTION part of a compound statement (see "Using compound statements"). The exception handler is executed whenever an error occurs in the compound statement. Unlike errors, warnings do not cause exception handling code to be executed. Exception handling code is also executed if an error is encountered in a nested compound statement or in a procedure or trigger that has been invoked anywhere within the compound statement.

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 is added to handle the column not found error in the InnerProc procedure.

CREATE PROCEDURE OuterProc()

BEGIN

   MESSAGE 'Hello from OuterProc.';

   CALL InnerProc();

   MESSAGE 'SQLSTATE set to ',

      SQLSTATE,' in OuterProc.'

END

CREATE PROCEDURE InnerProc()

BEGIN

   DECLARE column_not_found

      EXCEPTION FOR SQLSTATE '52003';

   MESSAGE 'Hello from InnerProc.';

   SIGNAL column_not_found;

   MESSAGE 'Line following SIGNAL.';

   EXCEPTION

      WHEN column_not_found THEN

         MESSAGE 'Column not found handling.';

      WHEN OTHERS THEN

   RESIGNAL ;

END

The EXCEPTION statement declares the exception handler itself. The lines following the EXCEPTION statement are not executed 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 is not 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 message window of the database engine then displays the following:

Hello from OuterProc.

Hello from InnerProc.

Column not found handling.

SQLSTATE set to 00000 in OuterProc.

Notes

♦	The lines following the SIGNAL statement in InnerProc are not executed; instead, the EXCEPTION statements are executed.

♦	As the error encountered was a column not found error, the MESSAGE statement included to handle the error is executed, and SQLSTATE is reset to zero (indicating no errors).

♦	After the exception handling code is executed, control is passed 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 is passed 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. As 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 undone. 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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Errors and warnings in procedures and triggers

Nested compound statements and exception handlers

The code following a statement that causes an error is not executed unless an ON EXCEPTION RESUME clause is included in a procedure definition.

You can use nested compound statements to give you more control over which statements are and are not executed following an error.

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

   DECLARE column_not_found

      EXCEPTION FOR SQLSTATE VALUE '52003';

      MESSAGE 'Hello from InnerProc';

      SIGNAL column_not_found;

         MESSAGE 'Line following SIGNAL'

   EXCEPTION

      WHEN column_not_found THEN

         MESSAGE 'Column not found handling';

      WHEN OTHERS THEN

         RESIGNAL;

      MESSAGE 'Outer compound statement';

END

The following statement executes the InnerProc procedure:

CALL InnerProc();

The message window of the database engine 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 is printed. Control then passes back to the outer compound statement and the Outer compound statement message is printed.

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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Using the EXECUTE IMMEDIATE statement in procedures

The EXECUTE IMMEDIATE statement allows statements to be built up 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

In ATOMIC compound statements, you cannot use an EXECUTE IMMEDIATE statement that causes a COMMIT, as COMMITs are not allowed in that context.


Transactions and savepoints in procedures and triggers
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Transactions and savepoints in procedures and triggers

SQL statements in a procedure or trigger are part of the current transaction (see the chapter "Using Transactions and Locks"). 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.


Some hints for writing procedures
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Some hints 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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Some hints for writing procedures

Check if you need to change the command delimiter

You do not need to change the command delimiter in ISQL or Sybase Central when you are writing procedures. However, if you are creating and testing 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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Some hints for writing procedures

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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Some hints for writing procedures

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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Some hints for writing procedures

Specifying dates and times in procedures

When dates and times are sent to the database from procedures, they are sent as strings. 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 sending dates to the database from procedures. These strings are interpreted unambiguously as dates by the database, 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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Some hints for writing procedures

Verifying that procedure input arguments are passed correctly

You can verify that input arguments to a procedure are passed correctly in several ways. For example:

♦	Display the value of the parameter on the message window of the database engine or server 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;

END

♦	From ISQL:

♦	Create a variable to hold the argument (say GBLVAR).

♦	Assign the argument to GBLVAR inside the procedure:

SET GBLVAR = argument

♦	After calling the procedure, display the value of GBLVAR:

SELECT GBLVAR

♦	Assign the input value to an output parameter, and test the value of the output parameter on completion.

♦	Insert the argument into a table, and SELECT from the table.


Statements allowed in batches
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Statements allowed in batches

The following statements are not allowed in batches:

♦	CONNECT or DISCONNECT statement

♦	ALTER PROCEDURE or ALTER FUNCTION statement

♦	CREATE TRIGGER statement

♦	ISQL commands such as INPUT or OUTPUT

Otherwise, any SQL statement is allowed, including data definition statements such as CREATE TABLE, ALTER TABLE, and so on.

The CREATE PROCEDURE statement is allowed, but must be the final statement of the batch.

 Using SELECT statements in batches


Using SELECT statements in batches
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Statements allowed in batches

Using SELECT statements in batches

You can include one or more SELECT statements in a batch. There are limitations on the use of more than one SELECT statements, just as in stored procedures: multiple SELECT statements are allowed only if they return the same result columns.

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 required only in the first SELECT statement, as the database engine uses the first SELECT statement in the batch to describe the result set.

A RESUME is required following each query to retrieve the next result set.

The following is not a valid batch, as the two queries return different result sets:

IF EXISTS( SELECT * FROM systable

      WHERE table_name='employee' )

THEN

   SELECT   emp_lname AS LastName,

            emp_fname AS FirstName

   FROM employee;

   SELECT id, lname, fname

   FROM customer;

END IF


Calling external libraries from stored procedures
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Calling external libraries from stored procedures

You can call a function in an external dynamic link library (DLL) from a stored procedure (including user-defined functions) under operating systems that support DLLs. You can also call functions in an NLM under NetWare. SQL Anywhere includes a set of system procedures that make use of this capability to send MAPI e-mail messages and carry out other functions. This section describes how to use the external library calls in procedures.

 Caution: — external libraries can corrupt your database—External libraries called from procedures share the memory of the database engine. If you call a DLL from a procedure and the DLL contains memory-handling errors, you can crash the database engine or corrupt your database. Ensure your libraries are thoroughly tested before deploying them on production databases.

For information on MAPI and other system procedures, see the chapter "SQL Anywhere System Procedures and Functions".

 Creating procedures and functions with external calls

 External function declarations

 How parameters are passed to the external function

 Special considerations when passing character types


Creating procedures and functions with external calls
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Calling external libraries from stored procedures

Creating procedures and functions with external calls

This section presents some examples of procedures and functions with external calls..

For a full description of CREATE PROCEDURE statement syntax,  see "CREATE PROCEDURE statement".

For a full description of the CREATE FUNCTION statement syntax for external calls, see "CREATE FUNCTION statement".

A procedure that calls a function function_name in DLL library.dll can be created as follows:

CREATE PROCEDURE dll_proc ( parameter-list )

EXTERNAL NAME 'function_name@library.dll'

Such a procedure is called an external stored procedure. 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 name of a function in the dynamic link library, and library.dll is the name of the library. The arguments in the procedure argument list must correspond in type and order to the arguments to the library function; they are passed to the external DLL function in the order in which they are listed. Any value returned by the external function is in turn returned by the procedure to the calling environment.

A procedure that calls an external function can include no other statements: its sole purposes are 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.

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 is to prefix the function name with the operating system name. For example:

CREATE PROCEDURE dll_proc ( parameter-list )

EXTERNAL NAME 'OS2:os2_fn@os2_lib.dll;WindowsNT:nt_fn@nt_lib.dll'

The operating system identifier must be one of OS2, WindowsNT, Windows95, Windows3X, or NetWare.

If no system identifier for the current operating system is provided, and a function with no system identifier is provided, that function is called.

NetWare calls have a slightly different format than the other operating systems. All symbols are globally known under NetWare, so that if a symbol (such as a function name) is exported, it must be unique to all NLMs on the system. Consequently, the NLM name is not necessary in the call, and it has the following syntax:

CREATE PROCEDURE dll_proc ( parameter-list )

EXTERNAL NAME 'NetWare:nw_fn'

No library name needs to be provided.


External function declarations
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Calling external libraries from stored procedures

External function declarations

When an external function is called, a stack is fabricated with the arguments (or argument references in the case of INOUT or OUT parameters) and the DLL is called. Only the following data types can be passed to an external library:

♦	CHARACTER data types, but INOUT and OUT parameters must be no more than 255 bytes in length

♦	SMALLINT and INT data types

♦	REAL and DOUBLE data types

This section describes the format of the function declaration.

For information about passing parameters to external functions, see "How parameters are passed to the external function"

In the external library, function declarations  should follow the following guidelines:

♦	Windows NT and Windows 95   The function declaration should be of the following form for the Watcom C/C++ compiler:

return-type * __export __stdcall function-name( argument-list )

and the following form for Microsoft Visual C++:

return-type * __declspec(dllexport) function-name( argument-list )

♦	Windows 3.x   All pointers are far pointers, so the DLL must be at least compiled under the large model. The function declaration should be of the following form for the Watcom C/C++ compiler:

return-type * __far __export __pascal function-name( argument-list )

For the 32-bit Windows 3.x engine or server, no more than 256 parameters can be used, of any type.

♦	OS/2   The function declaration should be of the following form for the Watcom C/C++ compiler:

return-type * __export __syscall function-name( argument-list )

♦	NetWare   The function declaration should be of the following form for the Watcom C/C++ compiler:

return-type  *


How parameters are passed to the external function
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Calling external libraries from stored procedures

How parameters are passed to the external function

SQL data types are mapped to their C equivalents as follows:

SQL data type	C data type
INTEGER	long
SMALLINT	short
REAL	float
DOUBLE	double
CHAR( n ) or VARCHAR ( n )	char *
These are the only SQL data types you can use: using others produces an error.

Procedure parameters that are INOUT or OUT parameters are passed to the external function by reference. For example, the procedure

CREATE PROCEDURE dll_proc( INOUT xvar REAL )

EXTERNAL NAME 'function_name@library.dll'

has an associated C function parameter declaration of

function_name( float * xvar )

Procedure parameters that are IN parameters are passed to the external function by value. For example, the procedure

CREATE PROCEDURE dll_proc( IN xvar REAL )

EXTERNAL NAME 'function_name@library.dll'

has an associated external function parameter declaration of

function_name( float xvar )

Character data types are an exception to IN parameters being passed. They are always passed by reference, whether they are IN, OUT, or INOUT parameters. For example, the procedure

CREATE PROCEDURE dll_proc ( IN invar CHAR( 128 ) )

EXTERNAL NAME 'function_name@library.dll'

has the following external function parameter declaration

function_name( char * invar )


Special considerations when passing character types
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 20. Using Procedures, Triggers, and Batches

Calling external libraries from stored procedures

Special considerations when passing character types

For character data types (CHAR or VARCHAR), the database engine allocates a 255-byte buffer (including one for the null terminator) for each parameter. If the parameter is an INOUT parameter, the existing value is copied into the buffer and null terminated, and a pointer to this buffer is passed to the external function. The external function should therefore not allocate a buffer of its own for OUT or INOUT character parameters: the engine has already allocated the space. If the external function writes beyond the 255 bytes (including the ending null character), it is writing over data structures in the database engine.

When the entry point returns, the parameter buffers are translated back into their engine data structure string equivalents based on the strlen() value of the buffer.

The external function should be sure to null-terminate any output string parameters. OUT parameters follow the same procedure except that as there is no initial data, no initial value of the output buffer parameter is guaranteed.


Monitoring and Improving Performance
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 21. Monitoring and Improving Performance

About this chapter

This chapter describes some of the methods available in SQL Anywhere to monitor and improve the performance of your database.

 Factors affecting database performance

 Using keys to improve query performance

 Using indexes to improve query performance

 Search strategies for queries from more than one table

 Sorting query results

 Temporary tables used in query processing

 How the optimizer works

 Monitoring database performance


Factors affecting database performance
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 21. Monitoring and Improving Performance

Factors affecting database performance

There are many factors that can affect database performance. This chapter describes ways of improving performance from a SQL perspective, and assumes a reasonably designed database running with sufficient resources. Disk and file management, as well as hardware configuration, also play an important part in determining performance. For example, the following can lead to poor performance:

Factors leading to poor database performance

♦	You are not running with a transaction log (see "T he transaction log"). A transaction log improves commit time for transactions that insert, update, or delete rows.

♦	You are using the 16-bit version of the Windows 3.x database engine. The 32-bit version has better performance, especially for larger databases.

♦	You are loading huge amounts of data into a database. See "Tuning bulk operations" for methods to improve performance.

♦	The database engine does not have an adequate amount of memory for caching database pages. See "The database engine" for command line options for controlling the cache size. Extra memory for your computer could improve database performance dramatically.

♦	Your hard disk is excessively fragmented. This becomes more important as your database increases in size. The DOS and Windows database engines cannot do direct (fast) reading and writing when the database file is very fragmented. There are several utilities available for DOS and Windows to defragment your hard disk. One of these should be run periodically. You could put the database on a DOS disk partition by itself to eliminate fragmentation problems.

♦	You are using a small page size for a large database. The page size is determined when the database is created by the initialization utility. You can find out the page size by using DBINFO. To change page size, you need to unload and reload your database.

♦	The database table design is not good. A bad database design can result in time-consuming queries to get information from the database. If indexes will not solve your performance problem, consider alternative database designs.

♦	Your hard disk is slow. A faster hard disk, a caching disk controller or a disk array can improve performance considerably.

♦	In a multiuser environment, your network performance is slow.

♦	You are fetching or inserting many rows of data. Consider using the multi-row operations.

♦	For more information, see "FETCH statement" and "PUT statement".


Using keys to improve query performance
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 21. Monitoring and Improving Performance

Using keys to improve query performance

The foreign key and the primary key are used for validation purposes. However, these keys are also used by SQL Anywhere to improve performance where possible.

Example

The following example illustrates how keys are used to make commands execute faster.

SELECT *

FROM employee

WHERE emp_id = 390

The simplest way for SQL Anywhere to perform 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 the search can take a long time.

The emp_id column is the primary key for the employee table. SQL Anywhere has a built-in index mechanism for finding primary and foreign key values quickly. (This mechanism is used for the validation you saw in "Validity checking".)

SQL Anywhere automatically uses the same mechanism to find the 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 table.

 Using ISQL to examine query performance

 Using primary keys to improve query performance

 Using foreign keys to improve query performance


Using ISQL to examine query performance
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 21. Monitoring and Improving Performance

Using keys to improve query performance

Using ISQL to examine query performance

The ISQL statistics window tells you when keys are being used to improve performance.

The number of lines in the statistics window can be adjusted or the window can be turned off altogether.

Changing the size of the statistics window

Under Windows, Windows NT and OS/2, the window can be resized in the standard manner. Click the mouse on the window border and drag it to the desired size. The window can be turned off by minimizing it. Restore the window by choosing Window [image] Statistics from the menu bar.

Under DOS and QNX, you can control the size of the statistics window with the SET OPTION STATISTICS command. The statistics window can also be turned on or off from the configuration window (choose Options [image] Configure from the menu bar). The Statistics option contains the number of lines in the statistics window. Use 0 to turn off the statistics window.

Information in the statistics window

If you execute a query to look at every row in the employee table:

SELECT *

FROM employee

two lines appear in the Statistics window:

75 rows in query (I/O estimate 1)

PLAN> employee (seq)

The first line indicates the number of rows in the query. Sometimes the database knows exactly, as in this case where there are 75 rows; other times it estimates the number of rows. The first line also indicates an internal I/O estimate of how many times SQL Anywhere will have to look at the database on your hard disk to examine the entire employee table.

The second line summarizes the execution plan for the query: the tables that are searched, any indexes used to search through a table. This plan says that SQL Anywhere will look at the employee table sequentially (that is, one page at a time, in the order that the rows appear on the pages). The letters seq inside parentheses mean that SQL Anywhere will examine all the rows of the table. This makes sense since the query fetches the entire table.

Resetting statistics

You may notice that when working through the tutorial yourself that the statistics window contains estimates than are different from what is given here. This may happen because the SQL Anywhere optimizer has decided to optimize a query differently. The optimizer maintains statistics as it evaluates queries and uses these statistics to optimize subsequent queries. These statistics can be reset by executing the following statement:

DROP OPTIMIZER STATISTICS

Note that you must have DBA authority to execute this statement.


Using primary keys to improve query performance
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 21. Monitoring and Improving Performance

Using keys to improve query performance

Using primary keys to improve query performance

SQL Anywhere uses a primary key to improve performance on the following statement:

SELECT *

FROM employee

WHERE emp_id = 390

Statistic window information

The statistics window contains the following two lines:

Estimated 1 rows in query (I/O estimate 13)

PLAN> employee (employee)

Whenever the name inside the parentheses in the ISQL statistics window PLAN description is the same as the name of the table, it means that SQL Anywhere will use the primary key for the table to improve performance. Also, the ISQL statistics window shows that the database optimizer estimates that there will be one row in the query and that it will have to go to the disk 13 times.


Using foreign keys to improve query performance
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 21. Monitoring and Improving Performance

Using keys to improve query performance

Using foreign keys to improve query performance

The following query lists the orders from customer with customer ID 113:

SELECT *

FROM sales_order

WHERE cust_id = 113

Statistic window information

The statistics window contains the following information:

Estimated 5 rows in query (I/O estimate 10)

PLAN> sales_order (ky_so_customer)

Here ky_so_customer refers to the foreign key that the sales_order table has for the customer table.

Primary and foreign keys are just special indexes that also maintain entity and referential integrity. The integrity is maintained by extra information that is placed in the indexes.


Using indexes to improve query performance
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 21. Monitoring and Improving Performance

Using indexes to improve query performance

Sometimes you need to search for something which is not in a primary or foreign key. Hence, SQL Anywhere cannot use a key to improve performance. Creating indexes speeds up searches on particular columns. For example, suppose you wanted to look up all the employees with a last name beginning with M.

A query for this is as follows:

SELECT *

FROM employee

WHERE emp_lname LIKE 'M%'

If you execute this command, the plan description in the ISQL statistics window shows that the table is searched sequentially.

Creating an index

If a search by employee last names is common, you may wish to create an index on the emp_lname column in order to speed up the queries. You can do this with a CREATE INDEX statement.

CREATE INDEX lname

ON employee ( emp_lname )

The column name emp_lname indicates the column that is indexed. An index can contain one, two, or more columns. However, if you create a multiple-column index, and then do a search with a condition using only the second column in the index, the index cannot be used to speed up the search. An index is similar to a telephone book which first sorts people by their last name, and then all the people with the same last name by their first name. A telephone book is useful if you know the last name, even more useful if you know both the first name and last name, but worthless if you only know the first name and not the last name.

Once you have created the index, rerunning the query produces the following plan description in the Statistics window:

PLAN> employee (lname)

How AQL Anywhere uses an index

SQL Anywhere uses the index automatically. Once an index is created, SQL Anywhere automatically keeps it up to date and uses it to improve performance whenever it can.

You could create an index for every column of every table in the database. But that would make data modifications slow, since SQL Anywhere would have to update all indexes affected by the change. Further, each index requires space in the database. For these reasons, you should only create indexes that are used frequently.

Since you will not be using this index again, you should delete it by entering the following statement:

DROP INDEX lname

 How indexes work


How indexes work
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 21. Monitoring and Improving Performance

Using indexes to improve query performance

How indexes work

This section provides a technical description of how the SQL Anywhere database engine uses indexes when searching databases.

Index page structure

The SQL Anywhere engine uses modified B+ trees. Each index page is a node in the tree and each node has many index entries. Leaf page index entries have a reference to a row of the indexed table. Indexes are kept balanced (uniform depth) and pages are kept close to full.

An index lookup

An index lookup starts with the root page. The index entries on a nonleaf page determine which child page has the correct range of values. The index lookup moves down to the appropriate child page. This continues until a leaf page is reached. An index with N levels will require N reads for index pages and 1 read for the data page that contains the actual row. Index pages tend to be cached due to the frequency of use.

Recommended page sizes

About the first 10 bytes of data for each index entry are stored in the index pages. This allows for a fan-out of roughly 200 using 4K pages, meaning that 200 rows can be indexed on one page, and 40,000 rows can be indexed 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. 4K pages are recommended for large databases.

The leaf nodes of the index are linked together. Once a row has been looked up, the rows of the table can be scanned in index order. Scanning all rows with a given value requires only one index lookup, followed by scanning the leaf nodes of the index until the value changes. This occurs when you have a WHERE clause that filters out rows with a certain value or a range of values. It also occurs when joining rows in a one-to-many relationship.


Search strategies for queries from more than one table
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 21. Monitoring and Improving Performance

Search strategies for queries from more than one table

This section uses sample queries to illustrate how SQL Anywhere selects an optimal processing route for each query. If you execute each of the commands in this section in ISQL, the statistics window display shows you the execution plan chosen by SQL Anywhere to process each query.

Using a key join

The following simple query uses a key join to search more than one table:

SELECT customer.company_name, sales_order.id

FROM sales_order

KEY JOIN customer

The Statistics window displays the following:

Estimated 711 rows in query (I/O estimate 2)

PLAN> customer(seq), sales_order(ky_so_customer)

When this query is executed, the ISQL statistics window display indicates that SQL Anywhere first examines each row in the customer table, then finds the corresponding sales order number in the sales_order table using the ky_so_customer foreign key joining the sales_order and customer tables.

The order that the tables are listed in the statistics window is the order that the tables are accessed by the database.

Adding a WHERE clause

If you modify the query by adding a WHERE clause, as follows, SQL Anywhere carries out the search in a different order:

SELECT customer.company_name, sales_order.id

FROM sales_order

KEY JOIN customer

WHERE sales_order.id = 2583

The Statistics windows displays the following plan:

PLAN> sales_order(sales_order), customer(customer)

Now, SQL Anywhere looks in the sales_order table first, using the primary key index. Then, for each sales order numbered 2583 (there is only one), it looks up the company_name in the customer table using the customer table primary key to identify the row. The primary key can be used here because the row in the sales_order table is linked to the rows of the customer table by the customer id number, which is the primary key of the customer table.

The tables are examined in a different order depending on the query. The SQL Anywhere built-in query optimizer estimates the cost of different possible execution plans, and chooses the plan with the least estimated cost.

For some more complicated examples, try the following commands which each join four tables. The ISQL statistics window shows that SQL Anywhere processes each query in a different order.

Example 1

 To list the customers and the sales reps they have dealt with.

1	Type the following:

SELECT  customer.lname,

employee.emp_lname

FROM customer

KEY JOIN sales_order

KEY JOIN sales_order_items

KEY JOIN employee

lname	emp_lname
Colburn	Chin
Smith	Chin
Sinnot	Chin
Piper	Chin
Phipps	Chin
The plan for this query is as follows:

PLAN> employee (seq), sales_order (ky_so_employee_id),

customer (customer), sales_order_items (id_fk)

Example 2

The following command restricts the results to list all sales reps that the customer named Piper has dealt with:

SELECT customer.lname,

employee.emp_lname

FROM customer

KEY JOIN sales_order

KEY JOIN sales_order_items

KEY JOIN employee

WHERE   customer.lname = 'Piper'

The plan for this query is as follows:

PLAN> customer (ix_cust_name), sales_order (ky_so_customer),

employee (employee), sales_order_items (id_fk)

Example 3

The third example shows all customers who have dealt with sales reps of the same name:

SELECT  customer.lname,

employee.emp_lname

FROM customer

KEY JOIN sales_order

KEY JOIN sales_order_items

KEY JOIN employee

WHERE  customer.lname = employee.emp_lname

The plan for this query is as follows:

PLAN> employee (seq), customer (ix_cust_name),

sales_order (ky_so_employee_id), sales_order_items (id_fk)

For information on how SQL Anywhere's optimizer selects a strategy for each search, see "How the optimizer works".


Sorting query results
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 21. Monitoring and Improving Performance

Sorting query results

Many queries against a database have an ORDER BY clause so that the rows come out in a predictable order. SQL Anywhere uses indexes to accomplish the ordering quickly. For example,

SELECT *

FROM customer

ORDER BY customer.lname

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.

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

The database engine must decide between two strategies:

♦	Go through the entire customer table in order by company name, checking each row to see if the customer id is greater than 300.

♦	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

The example above could be solved by creating a two-column index on id and company_name. (The order of the two columns is important.) The database engine could then use this index to select rows from the table and have them 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.


Temporary tables used in query processing
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 21. Monitoring and Improving Performance

Temporary tables used in query processing

Sometimes SQL Anywhere needs to make a temporary table for a query. This occurs in the following cases:

When temporary tables occur

♦	When a query has an ORDER BY or a GROUP BY and SQL Anywhere does not use an index for sorting the rows. Either no index was found or the optimizer chose a strategy that did not use the appropriate index for sorting.

♦	When a multiple-row update is being performed and the column being updated is used in the where clause of the update or in an index that is 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 an insert from a select statement is being performed and the select statement references the insert table.

♦	When a multiple row INSERT, UPDATE, or DELETE is performed, and there are triggers defined on the table that the operation causes to fire.

In these cases, SQL Anywhere makes a temporary table before the operation begins. The records affected by the operation are put into the temporary table and a temporary index is built on the temporary table. This operation of extracting the required records into a temporary table can take a significant amount of time before any rows at all are retrieved from the query. Thus, creating indexes that can be used to do the sorting in case 1 above will improve the performance of these queries since it will not be necessary to build a temporary table.

Notes

The insert, update and delete cases above are usually not a performance problem since it is usually a one-time operation. However, if it does cause problems, the only thing that can be done to avoid building a temporary table is to rephrase the command to avoid the conflict. This is not always possible.

In ISQL, the statistics window displays "TEMPORARY TABLE" before the optimization strategy is listed if a temporary table is created by SQL Anywhere in carrying out the search.


How the optimizer works
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 21. Monitoring and Improving Performance

How the optimizer works

The database engine has an optimizer that attempts to pick the best strategy for executing each query. The best strategy is the one that gets the results in the shortest period of time. The optimizer determines the cost of each strategy by estimating the number of disk reads and writes required. The strategy with the lowest cost is chosen.

The optimizer must decide which order to access the tables in a query, and whether or not to use an index for each table. If a query joins N tables, there are N factorial possible ways to access the tables. The optimizer will estimate the cost of executing the query in the different ways and use the ordering with the lowest cost estimate. The query execution plan in the ISQL statistics window shows the table ordering for the current query and indicates in parentheses the index that was used for each table.

 Optimizer estimates

 Self tuning of the query optimizer

 Providing estimates to improve query performance


Optimizer estimates
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 21. Monitoring and Improving Performance

How the optimizer works

Optimizer estimates

The optimizer uses heuristics (educated guesses) to help decide the best strategy.

For each table in a potential execution plan, the optimizer must estimate the number of rows that will be part of the results. The number of rows will depend on the size of the table and the restrictions in the WHERE clause or the ON clause of the query.

Percentage of rows that some comparison operations select

The table below shows the simplest guess at the percentage of rows that some of the comparison operations will select. The other comparison operations such as LIKE, IS NULL, and EXISTS are handled in a similar way.

Comparison	Percentage
=	5 (see below)
<>	95
<, <=, >, >=	25
between	6
In many cases, the optimizer uses more sophisticated heuristics. For example, the estimate of 5percent for equality is only used in cases where these other heuristics do not apply.

The optimizer makes use of indexes and keys to improve its guess of the number of rows. Here are a few single-column examples:

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: use the index to estimate the percentage of rows that will 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 rows for each primary row.


Self tuning of the query optimizer
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 21. Monitoring and Improving Performance

How the optimizer works

Self tuning of the query optimizer

One of the most common constraints in a query is equality with a column value. For example,

SELECT *

FROM employee

WHERE sex = 'f'

tests for equality of the sex column. For this type of constraint, the SQL Anywhere optimizer learns from its experience. A query will not always be optimized the same way the second time it is executed. The estimate for an equality constraint will be modified for columns that have an unusual distribution of values. This information is stored permanently in the database. If needed, the statistics can be deleted with the DROP OPTIMIZER STATISTICS command.


Providing estimates to improve query performance
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 21. Monitoring and Improving Performance

How the optimizer works

Providing estimates to improve query performance

Since the query optimizer is guessing at the number of rows in a result based on the size of tables and particular restrictions used in the WHERE clause, it almost always makes inexact guesses. In many cases, the guess that the query optimizer makes is close enough to the real number of rows that the optimizer will have chosen the best search strategy. However, in some cases this does not occur.

The following query displays a list of order items that shipped later than the end of June, 1994:

SELECT  ship_date

FROM  sales_order_items

WHERE ship_date > '1994/06/30'

ORDER BY ship_date DESC

The estimated number of rows is 274. However, the actual number of rows returned is only 12. This estimate is wrong because the query optimizer guesses that a test for greater than will succeed 25 percent of the time. In this example, the condition on the ship_date column:

ship_date > '1994/06/30'

is assumed to choose 25 percent of rows in the sales_order_items table.

Using an estimate

If you know that a condition has a success rate that differs from the optimizer rule, you can tell the database this information by using an estimate. An estimate is formed by enclosing in brackets the expression followed by a comma and a number. The number represents the percentage of rows that the expression is estimated to select. In this case, you could estimate a success rate of one percent:

SELECT  ship_date

FROM  sales_order_items

WHERE ( ship_date > '1994/06/30', 1 )

ORDER BY ship_date DESC

With this estimate, the optimizer estimates ten rows in the query.

Note

Incorrect estimates are only a problem when they lead to poorly optimized queries.


Monitoring database performance
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 21. Monitoring and Improving Performance

Monitoring database performance

SQL 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 database engine to the Windows NT performance monitor. The NT performance monitor can be used only to monitor Windows NT database engines or network servers.

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 NT performance monitor.

 Obtaining database statistics from a client application

 Monitoring database statistics from Sybase Central

 Monitoring database statistics from the NT Performance Monitor


Obtaining database statistics from a client application
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 21. Monitoring and Improving Performance

Monitoring database performance

Obtaining database statistics from a client application

SQL Anywhere provides a set of system functions that can access information on a per-connection, per-database, or engine-wide basis. The kind of information available ranges from static information such as the server name, the database file associated with a database, or the page-size of a database, to detailed performance-related statistics concerning disk and memory usage. The performance-related statistics are also available, along with some other statistics, for the Windows NT engine and server in the Windows NT Performance Monitor.

For more information on the Performance Monitor, see "Monitoring database statistics from the NT Performance Monitor".

This section illustrates how to use the functions.

A complete list of system functions and of the properties available using the system functions is provided in the section "System functions".

Functions that retrieve system information

The following functions are used to retrieve system information:

property   Provides the value of a given property on an engine-wide basis.

connection_property   Provides the value of a given property for a given connection, or for the current connection by default.

db_property   Provides the value of a given property for a given database, or for the current database by default. If you supply as argument only the name of the property you wish to retrieve, the functions return the value for the current server, connection, or database.

Examples

For example:

♦	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 maximum efficiency, 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 ISQL:

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.

Many of these statistics are made available in graphical form from the Sybase Central database management tool.


Monitoring database statistics from Sybase Central
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 21. Monitoring and Improving Performance

Monitoring database performance

Monitoring database statistics from Sybase Central

You can monitor database statistics from Sybase Central. The Sybase Central Performance Monitor is a graphing tool allowing database statistics to be plotted as a line graph or a bar graph.

 To start the Sybase Central Performance Monitor:

1	Click the icon for the server you wish to monitor in the left panel.

2	Double-click the Statistics folder underneath the server.

3	Select a statistic to graph, and drag it to the Performance Monitor icon to start graphing that statistic.

About the performance monitor

The Performance Monitor uses the regular SQL Anywhere communication mechanisms to gather statistics. This means some statistics (most notably Cache Reads) are affected by Sybase Central. For example, graphing Cache Reads/sec in Sybase Central shows a steady rate, even when nothing apart from the monitoring is going on.

If you have an NT client and server, the NT Performance monitor is preferable since it offers more statistics, and is not intrusive: updating the statistics will not affect the measurements. The extra statistics the NT performance monitor offers deal mainly with network communications—packets received, network buffers used, and so on.


Monitoring database statistics from the NT Performance Monitor
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 21. Monitoring and Improving Performance

Monitoring database performance

Monitoring database statistics from the NT Performance Monitor

The NT performance monitor is an application for viewing the behavior of objects such as processors, memory, and applications. SQL Anywhere provides many statistics for the performance monitor to display.

The NT performance monitor allows unintrusive monitoring of statistics: updating the statistics does not affect the measurements.

 To start the NT performance monitor:

1	Open the Administrative Tools program group.

2	Double click Performance Monitor.

For information about Performance Monitor, see the Performance Monitor online Help.

 To display SQL Anywhere statistics:

1	With Performance Monitor running, select Add To Chart from the Edit menu, or click the Plus sign on the toolbar.

The Add To Chart dialog appears.

2	From the Object list, select SQL Anywhere.

The Counter list then displays a list of the statistics provided.

3	From the Counter list, click a statistic to be displayed.

4	For a description of the selected counter, click Explain.

5	To display the counter, click Add.

6	When you have selected all the counters you wish to display, click Done.

Performance Monitor statistics

The statistics made available for Performance Monitor by SQL Anywhere are as follows:

Statistic	Description
Active Requests	Active Requests is the number of engine threads that are currently handling a request.
Asynchronous Reads/sec	Asynchronous Reads/sec is the rate at which pages are being read asynchronously from disk.
Asynchronous Writes/sec	Asynchronous Writes/sec is the rate at which pages are being written asynchronously to disk.
Bytes Received/sec	Bytes Received/sec is the rate at which network data (in bytes) are being received.
Bytes Transmitted/sec	Bytes Transmitted/sec is the rate at which bytes are being transmitted over the network.
Cache Hits/sec	Cache Hits/sec is the rate at which database page lookups are satisfied by finding the page in the cache.
Cache Index Internal Reads/sec	Cache Index Internal Reads/sec is the rate at which index internal-node pages are being read from the cache.
Cache Index Leaf Reads/sec	Cache Index Leaf Reads/sec is the rate at which index leaf pages are being read from the cache.
Cache Reads/sec	Cache Reads/sec is the rate at which database pages are being looked up in the cache.
Cache Table Reads/sec	Cache Table Reads/sec is the rate at which table pages are being read from the cache.
Cache Writes/sec	Cache Writes/sec is the rate at which pages in the cache are being modified (in pages/sec).
Checkpoint Flushes/sec	Checkpoint Flushes/sec is the rate at which ranges of adjacent pages are being written out during a checkpoint.
Checkpoint Log/sec	Checkpoint Log/sec is the rate at which the transaction log is being checkpointed.
Checkpoint Urgency	Checkpoint Urgency is expressed as a percentage. See documentation for details.
Checkpoints/sec	Checkpoints/sec is the rate at which checkpoints are being performed.
Commit files/sec	Commit files/sec is the rate at which the engine is forcing a flush of the disk cache. On NT and NetWare platforms, the disk cache does not need to be flushed since unbuffered (direct) IO is used.
Commits/sec	Commits/sec is the rate at which Commit requests are being handled.
Context Switch Checks/sec	Context Switch Checks/sec is the rate at which the current engine thread is volunteering to give up the CPU to another engine thread.
Context Switches/sec	Context Switches/sec is the rate at which the current engine thread is being changed.
Continue Requests/sec	Continue Requests/sec is the rate at which "CONTINUE" requests are being issued to the engine.
Corrupt Packets/sec	Corrupt Packets/sec is the rate at which corrupt network packets are being received.
Current IO	Current IO is the current number of file IOs issued by the engine which have not yet completed.
Current Reads	Current Reads is the current number of file reads issued by the engine which have not yet completed.
Current Writes	Current Writes is the current number of file writes issued by the engine which have not yet completed.
Cursor	Cursor is the number of declared cursors that are currently being maintained by the engine.
Dirty Pages	Dirty Pages is the number of pages in the cache which must be written out and which do not belong to temporary files.
Disk Index Internal Reads/sec	Disk Index Internal Reads/sec is the rate at which index internal-node pages are being read from disk.
Disk Index Leaf Reads/sec	Disk Index Leaf Reads/sec is the rate at which index leaf pages are being read from disk.
Disk Reads/sec	Disk Reads/sec is the rate at which pages are being read from file.
Disk SyncReads/sec	Disk SyncReads/sec is the rate at which pages are being read synchronously from disk.
Disk SyncWrite Other/sec	Disk SyncWrite Other/sec is the rate at which pages are being written synchronously to disk for a reason not covered by other "Disk SyncWrites _____/sec" counters.
Disk SyncWrites Checkpoint/sec	Disk SyncWrites Checkpoint/sec is the rate at which pages are being written synchronously to disk for a checkpoint.
Disk SyncWrites Extend/sec	Disk SyncWrites Extend/sec is the rate at which pages are being written synchronously to disk while extending a database file.
Disk SyncWrites Free Current/sec	Disk SyncWrites Free Current/sec is the rate at which pages are being written synchronously to disk to free a page that cannot remain in the in-memory free list.
Disk SyncWrites Free Push/sec	Disk SyncWrites Free Push/sec is the rate at which pages are being written synchronously to disk to free a page that can remain in the in-memory free list.
Disk SyncWrites Log/sec	Disk SyncWrites Log/sec is the rate at which pages are being written synchronously to the transaction log.
Disk SyncWrites Rollback/sec	Disk SyncWrites Rollback/sec is the rate at which pages are being written synchronously to the rollback log.
Disk SyncWrites/sec	Disk SyncWrites/sec is the rate at which pages are being written synchronously to disk. It is the sum of all the other "Disk SyncWrites _____/sec" counters.
Disk Table Reads/sec	Disk Table Reads/sec is the rate at which table pages are being read from disk.
Disk Waitreads/sec	Disk Waitreads/sec is the rate at which the engine is waiting synchronously for the completion of a read IO operation which was originally issued as an asynchronous read. Waitreads often occur due to cache misses on systems that support asynchronous IO.
Disk Waitwrites/sec	Disk Waitwrites/sec is the rate at which the engine is waiting synchronously for the completion of a write IO operation which was originally issued as an asynchronous write.
Disk Writes/sec	Disk Writes/sec is the rate at which modified pages are being written to disk.
Dropped Packets/sec	Dropped Packets/sec is the rate at which network packets are being dropped due to lack of buffer space.
Extend Database/sec	Extend Database/sec is the rate (in pages/sec) at which the database file is being extended.
Extend Temporary File/sec	Extend Temporary File/sec is the rate (in pages/sec) at which temporary files are being extended.
Free Buffers	Number of free network buffers.
Freelist Write Current/sec	Freelist Write Current/sec is the rate at which pages that cannot remain in the in-memory free list are being freed.
Freelist Write Push/sec	Freelist Write Push/sec is the rate at which pages that can remain in the in-memory free list are being freed.
Full compares/sec	Full compares/sec is the rate at which comparisons beyond the hash value in an index must be performed.
IO to Recover	IO to Recover is the estimated number of IO operations required to recover the database.
Idle Active/sec	Idle Active/sec is the rate at which the engine's idle thread becomes active to do idle writes, idle checkpoints, etc.
Idle Checkpoints/sec	Idle Checkpoints/sec is the rate at which checkpoints are completed by the engine's idle thread. An idle checkpoint occurs whenever the idle thread writes out the last dirty page in the cache.
Idle Waits/sec	Idle Waits/sec is the number of times per second that the server goes idle waiting for IO completion or a new request.
Idle Writes/sec	Idle Writes/sec is the rate at which disk writes are being issued by the engine's idle thread.
Index Fills	Index Fills is the number of times a new temporary merge index is created.
Index Merges	Index Merges is the number of times a temp index has been merged into a main index
Index adds/sec	Index adds/sec is the rate at which entries are being added to indexes.
Index lookups/sec	Index lookups/sec is the rate at which entries are being looked up in indexes.
Lock Table Pages	Lock Table Pages is the number of pages used to store lock information.
Main Heap Pages	Main Heap Pages is the number of pages used for global engine data structures.
Map Pages	Map Pages is the number of map pages used for accessing the lock table, frequency table, and table layout.
Maximum IO	Maximum IO is the maximum value that "Current IO" has reached.
Maximum Reads	Maximum Reads is the maximum value that "Current Reads" has reached.
Maximum Writes	Maximum Writes is the maximum value that "Current Writes" has reached.
Multi-packets Received/sec	Multi-packets Received/sec is the rate at which multi-packet deliveries are being received.
Multi-packets Transmitted/sec	Multi-packets Transmitted/sec is the rate at which multi-packet deliveries are being transmitted.
Open cursors	Open cursors is the number of open cursors that are currently being maintained by the engine.
Packets Received/sec	Packets Received/sec is the rate at which network packets are being received.
Packets Transmitted/sec	Packets Transmitted/sec is the rate at which network packets are being transmitted.
Page Relocations/sec	Page Relocations/sec is the rate at which relocatable heap pages are being read from the temporary file.
Pending requests/sec	Pending requests/sec is the rate at which the engine is detecting the arrival of new requests.
Ping1/sec	Ping1/sec is the rate at which ping requests which go all the way down into the engine are serviced.
Ping2/sec	Ping2/sec is the rate at which ping requests which are turned around at the top of the protocol stack are serviced.
Procedure Pages	Procedure Pages is the number of relocatable heap pages used for procedures.
Read Hints Used/sec	Read Hints Used/sec is the rate at which page-read operations are being satisfied immediately from cache thanks to a earlier read hint.
Read Hints/sec	A read hint is an asynchronous read operation for a page that the database engine is likely to need soon. Read Hints/sec is the rate at which such read operations are being issued.
Recovery Urgency	Recovery Urgency is expressed as a percentage. See documentation for details.
Redo Free Commits/sec	A "Redo Free Commit" occurs when a commit of the transaction (redo) log is requested but the log has already been written (so the commit was done for "free").
Redo Rewrites/sec	Redo Rewrites/sec is the rate at which pages that were previously written to the transaction log (but were not full) are being written to the transaction log again (but with more data added).
Redo Writes/sec	Redo Writes/sec is the rate at which pages are being written to the transaction (redo) log.
Relocatable Heap Pages	Relocatable Heap Pages is the number of pages used for relocatable heaps (cursors, statements, procedures, triggers, views, etc.).
Remoteput Wait/sec	Remoteput Wait/sec is the rate at which the communication link must wait because it does not have buffers available to send information. This statistic is collected for NetBIOS (both sessions and datagrams) and IPX protocols only.
Requests/sec	Requests/sec is the rate at which the engine is being entered to allow it to handle a new request or continue processing an existing request.
Rereads Queued/sec	A reread occurs when a read request for a page is received by the database IO subsystem while an asynchronous read IO operation has been posted to the operating system but has not completed. Rereads Queued/sec is the rate at which this condition is occurring.
Rereceived Packets/sec	Rereceived Packets/sec is the rate at which duplicate network packets are being received.
Retransmitted Packets/sec	Retransmitted Packets/sec is the rate at which network packets are being retransmitted.
Rollback Log Pages	Rollback Log Pages is the number of pages in the rollback log.
Rollback/sec	Rollbacks/sec is the rate at which Rollback requests are being handled.
SQL Anywhere	The SQL Anywhere object provides information about the Sybase SQL Anywhere Server, Client or Engine.
Sends Failed/sec	Sends Failed/sec is the rate at which the underlying protocol(s) failed to send a packet.
Statement	Statements is the number of prepared statements that are currently being maintained by the engine.
TotalBuffers	Total number of network buffers.
Trigger Pages	Trigger Pages is the number of relocatable heap pages used for triggers.
Unscheduled requests	Unscheduled requests is the number of requests that are currently queued up waiting for an available engine thread.
View Pages	View Pages is the number of relocatable heap pages used for views.
Voluntary blocks/sec	Voluntary blocks/sec is the rate at which engine threads voluntarily block on pending disk IO.
Waitread Full Compare/sec	Waitread Full Compare/sec is the rate at which read requests associated with a full comparison (a comparison beyond the hash value in an index) must be satisfied by a synchronous read operation.
Waitread Optimizer/sec	Waitread Optimizer/sec is the rate at which read requests posted by the optimizer must be satisfied by a synchronous read operation.
Waitread Other/sec	Waitread Other/sec is the rate at which read requests from other sources must be satisfied by a synchronous read operation.
Waitread SysConnection/sec	Waitread SysConnection/sec is the rate at which read requests posted from the system connection must be satisfied by a synchronous read operation. The system connection is a special connection used as the context before a connection is made and for operations performed outside of a any client connection.
Waitread Temporary Table/sec	Waitread Temporary Table/sec is the rate at which read requests for a temporary table must be satisfied by a synchronous read operation.


Database Collations
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 22. Database Collations

About this chapter

This chapter documents the built-in collations provided with SQL Anywhere and describes how to construct custom collations.

A collation is an ordering for a particular character set. Choosing the proper collation ensures that the sorting and comparison operations produce the proper results for the native language of the user.

 Collation overview

 Support for multibyte character sets

 Choosing a character set

 Creating custom collations

 The collation file format


Collation overview
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 22. Database Collations

Collation overview

When you create a SQL Anywhere database, you specify a collating sequence or collation to be used by the database. A collation is a sorting order for characters in the database. 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 submitted:

♦	Queries with an ORDER BY clause.

♦	Expressions that use string functions, such as LOCATE, SIMILAR, SOUNDEX.

♦	Conditions using the LIKE keyword.

The database also uses character sets in identifiers (column names and so on). In deciding whether a string is a valid or unique identifier, the database is using the database collation.

 Character sets in applications and databases

 Character encodings

 Displaying your current character settings

 Collation sequences


Character sets in applications and databases
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 22. Database Collations

Collation overview

Character sets in applications and databases

For character strings to be both sorted properly by the database and displayed properly in an application, it is important that the application and the database are using the same, or at least compatible, character sets. This section describes how the responsibilities for handling characters are divided between the database and the application.

Important components

Different aspects of character storage and display are separated out by operating systems. The following aspects are treated distinctly:

♦	Each operating system has a character set available to it. A character set is a set of symbols, including letters, digits, spaces and other symbols.

♦	Each operating system employs a character encoding, in which each character is mapped onto one or more bytes of information, typically represented as hexadecimal numbers.

♦	Characters are displayed on a screen using a font, which is a mapping between characters in the character set and their appearance.

♦	Operating systems also use a keyboard mapping to map keys or key combinations on the keyboard to characters in the character set.

♦	A collation is a combination of a character encoding (a map between characters and hexadecimal numbers) and a sorting order for the characters.

The database engine receives strings as a stream of hexadecimal numbers, which it associates with characters and sorts according to the collation specified when the database was created.

Character strings

It is up to the operating system of the computer on which the client application is running to handle the following aspects of character strings:

♦	Which character is stored when a particular key on the keyboard is typed.

♦	What a character looks like on your computer screen.

♦	What characters are available to the application.

♦	What hexadecimal encoding is stored for each character.

Notes

♦	It is important that the operating system and the database be using compatible character sets, character set encodings, and (if the application itself does any string sorting or comparison) collation sequences if information is to be handled and displayed in a consistent manner by the database engine and the client application.

♦	The ODBC interface provides mechanisms for translating strings on their way to the database engine, and on the way back, using a translation driver. For more information, see "Files needed for ODBC connections".


Character encodings
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 22. Database Collations

Collation overview

Character encodings

There are several different systems for encoding character sets as hexadecimal numbers. This section lists some of the more common.

Single-byte character sets and 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 two-digit hexadecimal number.

At most 256 characters can be represented in a single-byte set. No single single-byte character set can hold all the characters used, including accented characters, internationally. IBM developed a set of code pages in which each code page describes a set of characters appropriate for one national language. For example, code page 869 contains the Greek character set, code page 850 contains an international character set suitable for representing many characters in a variety of languages.

SQL Anywhere supports a set of single-byte collations (code pages and collation orderings) suitable for many languages of European origin.

For information about choosing a single-byte collation for your database, see "Choosing a character set".

Multibyte character sets

Some languages have many more than 256 characters, and these can be represented in multibyte character sets. In addition, there are character sets that use the much larger number of characters available in a multibyte representation to represent characters from many languages in a single, more universal, character set.

Multibyte character sets are of two types. Some are variable width, in which some characters are single-width 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. SQL Anywhere supports variable-width character sets.

For information on the multibyte character sets supported by SQL Anywhere, see "Support for multibyte character sets".


Displaying your current character settings
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 22. Database Collations

Collation overview

Displaying your current character settings

Each operating system has its own system for handling character sets, encodings, and collation sequences. To find out information about the current settings on your operating system, you can:

♦	In DOS or OS/2, type chcp at the command prompt to display the current code page.

♦	In Windows and Windows NT, see the International Settings in the Control Panel.

Character sets are stored by the operating system and sent to a database as a set of hexadecimal numbers.


Collation sequences
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 22. Database Collations

Collation overview

Collation sequences

Roughly speaking, a collation sequence is a sorting order for characters in a character set encoding or code page. The collation sequence is based on the encoded value of the characters.

The 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.

The collation sequence includes more information than a simple ordering. Each character is assigned to a sort position, and the sort position defines the position of that character in any comparison or sorting of character strings.

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 to be identical in all ways by the database. Therefore, if a collation assigned the characters a and e to the same sort order, 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- and uppercase forms of a character can be indicated. For case-sensitive databases, the lower- and uppercase characters are not treated as equivalent. For case-insensitive databases, the lower- and uppercase versions of the character are considered equivalent.


Support for multibyte character sets
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 22. Database Collations

Support for multibyte character sets

SQL Anywhere supports several multibyte character sets, including the following:

Multibyte character set	Description
SJIS	Japanese Shift-JIS Encoding
EUC_JAPAN	Japanese EUC JIS X 0208-1990 and JIS X 0212-1990 Encoding
EUC_CHINA	Chinese GB 2312-80 Encoding
EUC_TAIWAN	Taiwanese Big 5 Encoding
EUC_KOREA	Korean KS C 5601-1992 Encoding
UTF8	UTF8 is a variable-byte encoding of 4-byte unicode (UCS-4). SQL Anywhere supports UTF8 characters up to 4 bytes in length, while UTF8 may use up to 6 bytes.
This section describes how SQL Anywhere handles multibyte character sets. The description applies to the supported collations and to any custom collations.

 Variable length character sets

 First-byte collation orderings


Variable length character sets
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 22. Database Collations

Support for multibyte character sets

Variable length character sets

SQL Anywhere supports variable length 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. SQL Anywhere does not support fixed-length multibyte character sets such as 2-byte UNICODE or 4-byte UNICODE.

Example

As an example, characters in the Shift-JIS character set are of either one or two bytes in length. If the hex value of the first byte is in the range 81-9F or E0-EF (decimal values 129-159 or 224-239) then the character is a two-byte character and the subsequent byte (called a follow byte) completes the character. 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 (hex) range 09 to 0D, or 20, are space characters, those in the ranges 41 to 5A, 61 to 7A, 81 to 9F or E0 to EF are alpha characters (letters), and those in the range 30 to 39 are digits.

In building 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. However, all first bytes of value less than 40 (hex 28) must be single byte characters, and no follow bytes may have values less than 40. This restriction is satisfied by all known current encodings.


First-byte collation orderings
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 22. Database Collations

Support for multibyte character sets

First-byte collation orderings

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. If the two characters are the same up to the length of the shorter of the two, the longer character is greater than the shorter.


Choosing a character set
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 22. Database Collations

Choosing a character set

The best collation to use varies depending primarily on the language of the user and the code pages available in the user's machine. This will, of course, vary from one country or region to another.

The following table shows the built-in collations provided with SQL Anywhere. The table and the corresponding collations were derived from several manuals from IBM concerning National Language Support, subject to the restrictions mentioned above. (This table represents the best information available at the time of writing. Due to recent rapid geopolitical changes, the table may contain names for countries that no longer exist.)

Country	Language	Primary Code Page	Primary Collation	Secondary Code Page	Secondary Collation
Argentina	Spanish	850	850ESP	437	437ESP
Australia	English	437	437LATIN1	850	850LATIN1
Austria	German	850	850LATIN1	437	437LATIN1
Belgium	Belgian Dutch	850	850LATIN1	437	437LATIN1
Belgium	Belgian French	850	850LATIN1	437	437LATIN1
Belarus	Belarussian	855	855CYR
Brazil	Portuguese	850	850LATIN1	437	437LATIN1
Bulgaria	Bulgarian	855	855CYR	850	850CYR
Canada	Cdn French	850	850LATIN1	863	863LATIN1
Canada	English	437	437LATIN1	850	850LATIN1
Croatia	Croatian	852	852LATIN2	850	850LATIN2
Czech Republic	Czech	852	852LATIN2	850	850LATIN2
Denmark	Danish	850	850DAN
Finland	Finnish	850	850SVE	437	437SVE
France	French	850	850LATIN1	437	437LATIN1
Germany	German	850	850LATIN1	437	437LATIN1
Greece	Greek	869	869ELL	850	850ELL
Hungary	Hungarian	852	852LATIN2	850	850LATIN2
Iceland	Icelandic	850	850ISL	861	861ISL
Ireland	English	850	850LATIN1	437	437LATIN1
Israel	Hebrew	862	862HEB	856	856HEB
Italy	Italian	850	850LATIN1	437	437LATIN1
Mexico	Spanish	850	850ESP	437	437ESP
Nether-lands	Dutch	850	850LATIN1	437	437LATIN1
New Zealand	English	437	437LATIN1	850	850LATIN1
Norway	Norwegian	865	865NOR	850	850NOR
Peru	Spanish	850	850ESP	437	437ESP
Poland	Polish	852	852LATIN2	850	850LATIN2
Portugal	Portuguese	850	850LATIN1	860	860LATIN1
Romania	Romanian	852	852LATIN2	850	850LATIN2
Russia	Russian	866	866RUS	850	850RUS
S. Africa	Afrikaans	437	437LATIN1	850	850LATIN1
S. Africa	English	437	437LATIN1	850	850LATIN1
Slovak Republic	Slovakian	852	852LATIN2	850	850LATIN2
Slovenia	Slovenian	852	852LATIN2	850	850LATIN2
Spain	Spanish	850	850ESP	437	437ESP
Sweden	Swedish	850	850SVE	437	437SVE
Switzer-land	French	850	850LATIN1	437	437LATIN1
Switzer-land	German	850	850LATIN1	437	437LATIN1
Switzer-land	Italian	850	850LATIN1	437	437LATIN1
Turkey	Turkish	857	857TRK	850	850TRK
UK	English	850	850LATIN1	437	437LATIN1
USA	English	437	437LATIN1	850	850LATIN1
Venezuela	Spanish	850	850ESP	437	437ESP
Yugoslavia	Maced-onian	852	852LATIN2	850	850LATIN2
Yugoslavia	Serbian Cyrillic	855	855CYR	852	852CYR
Yugoslavia	Serbian Latin	852	852LATIN2	850	850LATIN2
When creating a new database

A user creating a new database should find the line with the country/language that they wish to use, then pick either the primary or secondary collation, depending on which code page is in use in their computer. (The chcp command will display the current code page number.) If their particular combination is not present, then another line with a satisfactory combination may be used, or a custom collation may be required.


Creating custom collations
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 22. Database Collations

Creating custom collations

To create a custom collation file, first use the DBCOLLAT utility to extract a collation from an existing database. A collation as close as possible to the wanted collation should be chosen.

Example 1

The following statement extracts the collation from a database named collat.db into a file named CUSTOM.COL:

dbcollat -c "dbf=collat.db;uid=dba;pwd=sql" custom.col

When you use DBCOLLAT to extract a collation from an existing database, the database does not need to contain any information. If you do not currently have a database using the collation on which you want to base a custom collation, you can create such as database using the Sybase Central administration tool or the DBINIT command line utility.

You can see a listing of available collations using DBINIT with the -l (lowercase L) option.

dbinit -l

Example 2

The following statement creates a database named COLLAT.DB using the Shift-JIS collation:

dbinit -z SJIS collat.db

Once you have extracted a collation file, you need to edit the file using a text editor to produce your custom collation file. The format of the custom collation file is described below.

To build a database that uses the custom collation file, use DBINIT with the -z switch. The following statement builds a database named COLLAT2.DB using the CUSTOM.COL custom collation file.

dbinit -z custom.col collat2.db


The collation file format
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 22. Database Collations

The collation file format

This section describes the collation file format. Collation files may include the following elements:

♦	Comment lines, which are ignored by the database.

♦	A title line.

♦	A collation sequence section.

♦	An Encodings section (multibyte character sets only).

♦	A Properties section (multibyte character sets only).

 Comment lines

 The title line

 The collation sequence section

 The Encodings section

 The Properties section


Comment lines
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 22. Database Collations

The collation file format

Comment lines

In the collation file, spaces are generally ignored. Comment lines start with either % or --.


The title line
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 22. Database Collations

The collation file format

The title line

The first non-comment line must be of the form:

Collation label (name)

In this statement:

Item	Description
Collation	a keyword and is required
label	is the collation label and appears in the system tables as SYS.SYSCOLLATION.collation_label and SYS.SYSINFO.default_collation. The label must be no more than 10 characters, and must not be the same as one of the built-in collations. (In particular, do not leave the collation label unchanged.)
name	a descriptive term, used for documentation purposes. The name should be no more than 128 characters For example, the Shift-JIS collation file contains the following collation line, with label SJIS and name (Japanese Shift-JIS Encoding): Collation SJIS (Japanese Shift-JIS Encoding)


The collation sequence section
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 22. Database Collations

The collation file format

The collation sequence section

After the title line, each noncomment line describes one position in the collation. The ordering of the lines determines the sort ordering used by the database, and also 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

or

[sort-position] : character [lowercase uppercase]

where:

Descriptions of arguments

Argument	Description
sort-position	is optional and 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 item. Typically, the sort-position is omitted, and the characters sort immediately following the characters from the previous sort position
character	is the character whose sort-position is being specified
lowercase	is optional and specifies the lowercase equivalent of the character. If not specified, then the character has no lowercase equivalent
uppercase	is optional and specifies the uppercase equivalent of the character. If not specified, then the character has no uppercase 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 sortposition is specified in one of the following ways:

Specification	Description
\dnnn	Decimal number, using digits 0-9 (such as \d001)
\xhh	Hexadecimal number, using 2 digits 0-9 and/or 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 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 % Sort some special characters at the end: : ' ' : _ : \xF2 : \xEE : \xF0 : - : ',' : ; : ':' : !
Other syntax notes

For databases using case-insensitive sorting and comparing (no -c specified on the DBINIT command line), the lowercase and uppercase mappings are used to find the lowercase and uppercase characters that will be 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 second byte. For example, the following is part of a 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 will be added to the collation at the position equal to their binary value. DBINIT issues a message for each omitted character. However, it is recommended that any collation contain all 256 characters (first bytes).


The Encodings section
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 22. Database Collations

The collation file format

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 those combinations of bytes which are valid characters. The format of the section may be described by example.

The Shift-JIS Encodings section is as follows:

Encodings:

[\x00-\x80,\xa0-\xdf,\xf0-\xff]

[\x81-\x9f,\xe0-\xef][\x00-\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 double-byte characters. Any combination of bytes from ranges in the first pair of brackets with those in the second are valid characters. Therefore \x81\x00 is a valid double-byte character, but \xd0 \x00 is not.


The Properties section
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 22. Database Collations

The collation file format

The Properties section

The Properties section is optional, and follows the Encodings section. It is not useful for single-byte character sets.

If a Properties section is supplied, an Encodings section must be supplied also.

The Properties section lists values for the first-byte of each character that represent 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.


Importing and Exporting Data
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 23. Importing and Exporting Data

About this chapter

Transferring large amounts of 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

♦	Exporting data into other applications, such as spreadsheets

♦	Building new copies of a database with modified structure

♦	Creating extractions of a database

This chapter describes how to import data to and export data from SQL Anywhere databases, both in text form and in other formats.

 Import and export overview

 Exporting data from a database

 Importing data into a database

 Tuning bulk operations


Import and export overview
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 23. Importing and Exporting Data

Import and export overview

SQL Anywhere supports import and export of individual tables or a complete database using text files. Importing and exporting data to other formats, such as spreadsheet program formats, is available from the ISQL utility.

The LOAD TABLE statement and the UNLOAD TABLE statement are the SQL statements for loading and unloading tables using text files. The INPUT statement and the OUTPUT statement are ISQL commands for importing and exporting data using a variety of formats.

You can unload individual tables or a complete database from SQL Central, using the Unload Database wizard. You can also unload individual tables or a complete database using the DBUNLOAD command line utility. The DBUNLOAD utility is accessible from ISQL.

This chapter describes the LOAD TABLE and UNLOAD TABLE SQL statements, as well as the use of SQL Central, DBUNLOAD, and ISQL to import and export data.

 Input and output data formats


Input and output data formats
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 23. Importing and Exporting Data

Import and export overview

Input and output data formats

The LOAD TABLE and UNLOAD TABLE import and export text files, with one row per line, and values separated by a delimiter.

The ISQL INPUT and OUTPUT statements support the following file formats:

File Format	Description
ASCII	A text file, one row per line, with values separated by a delimiter. String values are optionally enclosed in apostrophes (single quotes). This is the same as the format used by LOAD TABLE and UNLOAD TABLE
DBASEII	DBASE II format
DBASEIII	DBASE III format
DIF	Data Interchange Format
FIXED	Data records are in fixed format with the width of each column either the same as defined by the column's type or specified as a parameter
FOXPRO	FoxPro format
LOTUS	Lotus workspace format
WATFILE	WATFILE format. There is an ISQL option for the default input format and one for the default output format. For details on how to specify this option, see "SET OPTION statement". Alternatively, the file format can be specified on each INPUT statement or OUTPUT statement


Exporting data from a database
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 23. Importing and Exporting Data

Exporting data from a database

You can export data from your database using one of the following methods:

♦	The UNLOAD TABLE statement, for efficient export of text files

♦	The ISQL OUTPUT statement, for slower but more flexible export to a variety of file formats

♦	The DBUNLOAD utility, for text export of more than one table

This section describes each of these methods, and also describes some tips for dealing with NULL output.

 Unloading data using the UNLOAD TABLE statement

 Exporting data using the ISQL OUTPUT statement

 Output redirection

 NULL value output

 Unloading a database using DBUNLOAD


Unloading data using the UNLOAD TABLE statement
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 23. Importing and Exporting Data

Exporting data from a database

Unloading data using the UNLOAD TABLE statement

The UNLOAD TABLE statement is for efficient export of data from a database table to a text file. You must have SELECT permission on the table to use the UNLOAD TABLE statement.

Example 1

The following statement unloads the department table from the sample database into the file DEPT.TXT in the current directory of the drive on which the database engine is running. If you are running against a network server, the command unloads the data into a file on the server machine, not the client machine.

UNLOAD TABLE department

TO 'dept.txt'

The dept.txt file has the following contents:

100,'R & D',501

200,'Sales',902

300,'Finance',1293

400,'Marketing',1576

500,'Shipping',703

Notes

♦	Each row of the table is output on a single line of the output file.

♦	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 number of characters in each entry are exported, not the full width of the column.

♦	The character data in the dept_name column is enclosed in single quotes. The single quotes can be turned off using the QUOTES clause.

♦	The data is exported by primary key values. This makes reloading quicker. You can export data in the order in which it is stored using the ORDER OFF clause.

♦	The file name is relative to the database engine's current directory, not the current directory of the client application. Also, the file name is passed to the database engine as a string, so that special characters need to be preceded by a backslash (\) in order to be recognized. For example, the following statement unloads a table into the file c:.temp.output.dat:

UNLOAD TABLE employee TO 'c:\temp\output.dat'

For more information on the syntax, see "UNLOAD TABLE statement".

Example 2

The following example uses explicit settings for the DELIMITED BY and QUOTES clauses:

UNLOAD TABLE department

TO 'dept.txt'

DELIMITED BY '$'

QUOTES OFF

The resulting dept.txt file has the following contents:

100$R & D$501

200$Sales$902

300$Finance$1293

400$Marketing$1576

500$Shipping$703

If a delimiter character appears in a value in a column and the QUOTES option is turned off, the character is replaced by its hexadecimal value preceded by \x to prevent ambiguity as to the end of the value. For example:

UNLOAD TABLE department

TO 'dept.txt'

DELIMITED BY '&'

QUOTES OFF

yields the following output file.

100&R \x26 D&501

200&Sales&902

300&Finance&1293

400&Marketing&1576

500&Shipping&703


Exporting data using the ISQL OUTPUT statement
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 23. Importing and Exporting Data

Exporting data from a database

Exporting data using the ISQL OUTPUT statement

Data can be exported from a database to a variety of file formats using the ISQL OUTPUT statement. This statement exports the results of the current query (the one displayed in the ISQL. data window) and puts the results into a specified file. The output format can be specified on the output command.

For example, the following commands extract the employee table to a dBaseIII format file:

SELECT *

FROM employee;

OUTPUT TO employee.dbf

FORMAT dbaseiii;


Output redirection
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 23. Importing and Exporting Data

Exporting data from a database

Output redirection

Output redirection can be used to export data as an alternative to the OUTPUT statement.

The output of any command can be redirected to a file or device by putting the ># redirection symbol anywhere on the command. The redirection symbol must be followed by a file name, as follows:

># filename

Output redirection is most useful on the SELECT statement. The SET OUTPUT_FORMAT command can be used to control the format of the output file.

Example

The >& redirection symbol redirects all output including error messages and statistics for the command on which it appears. For example:

SELECT *

FROM employee >& filename

outputs the SELECT statement to the file, followed by the output from the SELECT statement and some statistics pertaining to the command.

The >& redirection is useful for getting a log of what happens during a READ command. The statistics and errors of each command are written following the command in the redirected output file.

If two > characters are used in a redirection symbol instead of one (>>#, >>&.), then the output is appended to the specified file instead of replacing the contents of the file. For output from the SELECT command, headings are output if and only if the output starts at the beginning of the specified file and the output format supports headings.


NULL value output
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 23. Importing and Exporting Data

Exporting data from a database

NULL value output

The most common reason to extract data is for use in other software products. When your data includes NULL values, the other software package may not understand the NULL values.

There is an ISQL option (NULLS) that allows you to choose how NULL values are output. Alternatively, you can use the IFNULL function to output a specific value whenever there is a NULL value.

For information on setting ISQL options, see "SET OPTION statement".


Unloading a database using DBUNLOAD
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 23. Importing and Exporting Data

Exporting data from a database

Unloading a database using DBUNLOAD

The DBUNLOAD utility supplied with SQL Anywhere is used to unload an entire database in ASCII comma-delimited format and to create the necessary ISQL. command files to completely recreate your database. This may be useful for creating extractions, creating a backup of your database or building new copies of your database with the same or slightly modified structure.

It is particularly useful if you want to rearrange your tables in the database. Use DBUNLOAD to create the necessary command files and modify them as needed.

Exporting a list of tables

The DBUNLOAD utility can also export a list of tables, rather than the entire database. This is useful for retrieving data from a corrupted database that cannot be entirely unloaded.

The following statement 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.

dbunload -c "dbn=sademo;uid=dba;pwd=sql" c:\temp

For Windows 3.x, the DBUNLOAD executable is named DBUNLOAW.EXE. For a full description of dbunload utility command-line switches, see the section "The Unload utility".


Importing data into a database
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 23. Importing and Exporting Data

Importing data into a database

You can import data into your database using one of the following methods:

♦	The LOAD TABLE statement, for efficient import of text files.

♦	The ISQL INPUT statement, for slower but more flexible import of a variety of file formats.

♦	Interactive input using the INSERT Statement or the ISQL INPUT statement.

This section describes each of these methods, and also describes some tips for dealing with incompatible data structure and conversion errors.

 Loading data using the LOAD TABLE statement

 Importing data using the ISQL INPUT statement

 Loading data interactively

 Handling conversion errors on data import

 Loading data that does not match the table structure


Loading data using the LOAD TABLE statement
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 23. Importing and Exporting Data

Importing data into a database

Loading data using the LOAD TABLE statement

The LOAD TABLE statement is for efficient importing of data from a text file into a database table. To use the LOAD TABLE statement, the table must exist and have the same number of columns as the input file has fields, defined on compatible data types. In order to use the LOAD TABLE statement, the user must have INSERT permission on the table.

Example

If the department table had all its rows deleted, the following statement would load the data from the file dept.txt into the department table:

LOAD TABLE department

FROM 'dept.txt'

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.

The LOAD TABLE statement has many of the same options as the UNLOAD TABLE statement.

For a description of column delimiters, use of quotes, and file names, see the section "Unloading data using the UNLOAD TABLE statement".

The LOAD TABLE statement has the additional STRIP clause. The default setting (STRIP ON) strips trailing blanks from values before they are inserted. To keep trailing blanks, use the STRIP OFF clause in your LOAD TABLE statement.

For a full description of the LOAD TABLE statement syntax, see "LOAD TABLE statement".


Importing data using the ISQL INPUT statement
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 23. Importing and Exporting Data

Importing data into a database

Importing data using the ISQL INPUT statement

Data with the same structure as existing database tables can be loaded into your database from a file using the ISQL INPUT statement.

The ISQL INPUT statement is less efficient than the LOAD TABLE statement for importing text files. However, the INPUT statement supports several different file formats, whereas the LOAD TABLE statement can be used only for text files.

The INPUT command can be entered in ISQL as follows:

INPUT INTO t1

FROM file1

FORMAT ASCII;

INPUT INTO t2

FROM file2

FORMAT FIXED

COLUMN WIDTHS (5, 10, 40, 40 );

...

These statements could be put in a command file which can then be executed in ISQL for modification and reference.

For more information about command files, see the tutorial chapter "Command Files".


Loading data interactively
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 23. Importing and Exporting Data

Importing data into a database

Loading data interactively

There are two commands that can be used to input data interactively. You can use the insert command:

INSERT INTO T1 VALUES ( ... )

to insert a single row at a time or you can use the input command:

INPUT INTO T1 PROMPT

which gives you a full screen to type in data in the current input format (controlled by the ISQL INPUT_FORMAT option).


Handling conversion errors on data import
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 23. Importing and Exporting Data

Importing data into a database

Handling conversion errors on data import

When you are loading 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. There is an ISQL database option (CONVERSION_ERROR) that allows you to ignore conversion errors by converting them to NULL values.

For information on setting ISQL database options, see "SET OPTION statement".


Loading data that does not match the table structure
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 23. Importing and Exporting Data

Importing data into a database

Loading data that does not match the table structure

The structure of the data to be loaded into a table does not always match the structure of the destination table itself. For example, the column data types may be different, or in different order, or there may be extra values in the data to be imported that do not match columns in the destination table.

You can use a stepwise approach to load data that has a different structure to the destination table:

♦	Using the LOAD TABLE statement, load the data into a temporary table that has a structure matching that of the input file.

♦	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 of the permanent database tables.

DECLARE TEMPORARY TABLE statement

If you are loading a set of data once and for all, you should make the temporary table using the DECLARE TEMPORARY TABLE statement. A declared temporary table exists only for the duration of a connection or, if defined inside a compound statement, of the compound statement.

CREATE TABLE statement

If you are loading data of a similar structure repeatedly, you should make the temporary table using the CREATE TABLE statement, specifying a global temporary table. The definition of a created temporary table is held in the database permanently, but the rows exist only within a given connection.


Tuning bulk operations
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 23. Importing and Exporting Data

Tuning bulk operations

Loading large volumes of data into a database can be very time consuming. There are a few things you can do to save time.

♦	Run ISQL or the client application on the same machine as the database engine. Loading data over the network adds extra communication overhead. This might mean loading new data during off hours.

♦	Place data files on a separate physical disk drive from the database file. This could avoid excessive disk head movement during the load.

♦	In Windows 3.x, if your computer has a 386, 486, or higher processor, use the 32-bit database engine rather than the 16-bit database engine.

♦	Increase the size of the database cache. See the chapter "SQL Anywhere Components" for a description of the database engine command line option -c. Eliminate disk cache in favor of database cache if the machine is a dedicated SQL Anywhere server.

♦	Start the database engine or network server with the -b switch for bulk operations mode. In this mode, the database engine does not keep a rollback log or a transaction log, it does not perform an automatic COMMIT before data definition commands, and it does not lock any records. Without a rollback log, you cannot use savepoints and aborting a command always causes transactions to roll back. Without automatic COMMIT, a ROLLBACK undoes everything since the last explicit COMMIT. Without a transaction log, there is no log of the changes. You should back up the database file before and after using bulk operations mode because, in this mode, your database is not protected against media failure (see the chapter "Backup and Data Recovery").

♦	The network server allows only one connection when you use the -b switch.

♦	If you have data that requires many COMMITs, running with the -b option may slow down database operation. At each COMMIT, the engine carries out a checkpoint; this frequent checkpointing can slow down the database engine.

♦	Extend the size of the database file using ALTER DBSPACE (see the chapter "Watcom-SQL Language Reference"). This command allows a database file to be extended in large amounts before the space is required, rather than the normal 32 pages 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 files more contiguous within the file system.


Managing User IDs and Permissions
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

About this chapter

Each user of a database must be assigned a user ID: the name they type when connecting to the database. This chapter describes how to manage user IDs.

 An overview of database permissions

 Managing individual user IDs and permissions

 Managing groups

 Database object names and prefixes

 Using views and procedures for extra security

 How SQL Anywhere assesses user permissions

 Users and permissions in the system tables


An overview of database permissions
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

An overview of database permissions

Proper management of user IDs and permissions is essential for users of a database to carry out their jobs effectively while maintaining the security and privacy of appropriate information within the database.

SQL Anywhere provides commands 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. You should remember, however, that it is always on the basis of a particular user ID that permissions are granted and revoked.

Setting up individual user IDs

Even if there are no security concerns regarding a multiuser database, there are good reasons for setting up an individual user ID for each user, and the administrative overhead is very low if a group with the appropriate permissions is set up. Groups of users are discussed in this chapter. Among other reasons for using individual user IDs are the following:

♦	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.

♦	The network server screen and the listing of connections in Sybase Central are both much more useful 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

 Resource authority overview

 Ownership permissions overview

 Table and views permissions overview

 Procedures permissions overview

 Group permissions overview


DBA authority overview
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

An overview of database permissions

DBA authority overview

When a SQL Anywhere database is created using the DBINIT tool, a single usable user ID is created. This first user ID is DBA and the password is initially set to SQL. The DBA user ID is automatically given DBA permissions, also called DBA authority, within the database. This level of permission enables the DBA user ID to carry out any activity in the database: 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 is referred to as the database administrator or database owner. In this chapter frequent reference is made to the database administrator, or the DBA. This is a shorthand for any user or users with DBA authority.

Although DBA authority may be granted or transferred to other user IDs, in this chapter it is assumed that the DBA user ID is the database administrator, and the abbreviation DBA is used interchangeably to mean 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 users are added, 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

See the syntax of the commands for creating database objects, in the chapter "Watcom-SQL Language Reference".


Resource authority overview
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

An overview of database permissions

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 other users.

In order to create a trigger, a user needs ALTER permissions on the table to which the trigger applies, in addition to RESOURCE authority.


Ownership permissions overview
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

An overview of database permissions

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 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, for instance. The DBA has all the permissions regarding database objects that the owners of each object has.

The DBA is also able to create database objects for other users, and 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.


Table and views permissions overview
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

An overview of database permissions

Table and views permissions overview

There are several distinct permissions that may be granted to user IDs concerning tables:

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
Convenient and secure access to data in each table is set by granting combinations of these permissions to different sets of users.


Procedures permissions overview
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

An overview of database permissions

Procedures permissions overview

There is only one permission that may be granted on a procedure, and that is the EXECUTE permission to execute (or CALL) the procedure.


Group permissions overview
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

An overview of database 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 is made a member of the sales group, and automatically gains access to the appropriate areas of the database.

Any user ID can be a member of several groups, and inherits all permissions from each of the groups.


Managing individual user IDs and permissions
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

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 groups are simply a user ID with special properties attached, you should read and understand this section before moving on to the discussion of managing groups.

 Creating new users

 Changing a password

 Granting DBA and resource authority

 Granting permissions on tables and views

 Granting users the right to grant permissions

 Granting permissions on procedures

 Execution permissions of triggers

 Revoking user permissions


Creating new users
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

Managing individual user IDs and permissions

Creating new users

A new user is added to a database by the DBA using the GRANT CONNECT statement. For example:

 To add a new user to a database, with user ID M_Haneef and password welcome:

1	From ISQL, connect to the database as a user with DBA authority.

2	Issue the SQL statement:

GRANT CONNECT TO M_Haneef

IDENTIFIED BY welcome

Only the DBA has the authority to add new users to a database.

Initial permissions for new users

By default, new users are not assigned any permissions beyond connecting to the database and viewing the system tables. In order to access tables in the database they 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".

Creating users in Sybase Central

 To create a user in Sybase Central:

1	Connect to the database.

2	Click the Users and Groups folder for that database.

3	Double-click Add User. A Wizard is displayed, which leads you through the process.

For more information, see the Sybase Central online Help.


Changing a password
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

Managing individual user IDs and permissions

Changing a password

Changing a users password

You can change your password, or that of another user if you have DBA authority, using the GRANT statement. 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 SQL Anywhere 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

DBA must be enclosed in double quotes in this expression as it is a SQL Anywhere keyword.

If you are using ISQL, it is a good idea to put your permission grants into a command file for reference and so that it can be modified and run again if it is necessary to recreate the permissions.


Granting DBA and resource authority
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

Managing individual user IDs and permissions

Granting DBA and resource authority

DBA and RESOURCE authority are granted in exactly the same manner as each other.

 To grant resource permissions to user ID M_Haneef:

1	Connect to the database as a user with DBA authority.

2	Type and execute the SQL statement:

GRANT RESOURCE TO M_Haneef.

For DBA authority, the appropriate SQL statement is:

GRANT DBA TO M_Haneef

Notes

♦	Only the DBA may grant DBA or RESOURCE authority to database users.

♦	DBA authority is very powerful, granting the ability to carry out any action on the database and access to all the information in the database. It is generally inadvisable to grant DBA authority to more than a very few people.

♦	You should 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 and views
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

Managing individual user IDs and permissions

Granting permissions on tables and views

SQL Anywhere provides a set of permissions on individual tables and views. Users can be granted combinations of these permissions to define their access to a table or view.

Combinations of permissions

♦	The ALTER (permission to alter the structure of a table or to create triggers on a table) and REFERENCES (permission to create indexes on a table, and to create foreign keys) 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 or view. 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 or view, but does not give permission to alter it.

♦	Granting ALL permissions grants all the above permissions.

Example 1

All table and view 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:

♦	Connect to the database as a user with DBA authority, or as the owner of sample_table.

♦	Type and execute the 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:

♦	Connect to the database as a user with DBA authority, or as the owner of sample_table.

♦	Type and execute the SQL statement: GRANT UPDATE column_1, column_2 ON sample_table TO M_Haneef

One limitation of table and view permissions is that they apply to all the data in a table or view (except for the UPDATE permission which may be restricted). Finer tuning of user permissions can be accomplished by creating procedures that carry out actions on tables, and then granting users the permission to execute the procedure.

Procedure permissions are discussed in "Granting permissions on procedures".


Granting users the right to grant permissions
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

Managing individual user IDs and permissions

Granting users the right to grant permissions

Each of the table and view permissions described in "Granting permissions on tables and views" can be assigned WITH GRANT OPTION. This option gives the right to pass on the permission to other users. This feature is discussed in the context of groups in section "Permissions of groups".

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:

♦	Connect to the database as a user with DBA authority, or as the owner of sample_table:

♦	Type and execute the SQL statement:

GRANT DELETE ON sample_table

TO M_Haneef

WITH GRANT OPTION

Granting user permissions on tables in Sybase Central

One way to grant a user permissions on a table in Sybase Central is as follows:

♦	Connect to the database.

♦	Double-click the Tables folder for that database to display the tables in the left panel.

♦	Click the Users and Groups folder, and locate the user you want to grant permissions to.

♦	Drag the user to the table for which you want to grant permissions.

For more information, see the Sybase Central online Help.


Granting permissions on procedures
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

Managing individual user IDs and permissions

Granting permissions on procedures

Permission to execute stored procedures may be granted by the DBA or by the owner of the procedure (the user ID that created the 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 and views".

Example

You can grant M_Haneef permission to execute a procedure named my_procedure, as follows:

♦	Connect to the database as a user with DBA authority or as owner of my_procedure procedure.

♦	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 on a table will execute successfully only if the owner of the procedure has UPDATE permissions on the table. As long as the procedure owner does have the proper permissions, the procedure will execute 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.

Granting user permissions on procedures in Sybase Central

One way to grant a user permissions on a table in Sybase Central is as follows:

♦	Connect to the database.

♦	Click the Users and Groups folder, and locate the user you want to grant permissions to.

♦	Right-click the user, and select Copy from the popup menu.

♦	Locate the procedure you want to allow the user to execute, in the Stored Procedures folder.

♦	Click the procedure, and choose Edit [image] Paste from the main menu to grant permissions.

For more information, see the Sybase Central online Help.


Execution permissions of triggers
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

Managing individual user IDs and permissions

Execution permissions of triggers

Triggers are executed by the database engine in response to a user action; no permissions are required for triggers to be executed. When a trigger executes, it does have permissions associated with it that determine its ability to carry out actions.

Triggers execute with the permissions of the creator of the table with which they are associated.

For more information on trigger permissions, see "Trigger execution permissions".


Revoking user permissions
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

Managing individual user IDs and permissions

Revoking user permissions

The ability to revoke permissions is useful in order to take away permissions that have been explicitly granted to a user, but which are no longer appropriate.

More than this, any user's permissions are a combination of those that have been granted and those that have been revoked. Revoking and granting permissions work together in managing 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

This command must be issued by the DBA or by the owner of the procedure. Permission to delete rows from sample_table may be revoked by issuing the command:

REVOKE DELETE ON sample_table FROM M_Haneef


Managing groups
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

Managing groups

Once you understand how to manage permissions for individual users (as described in the previous section) working with groups is straightforward. A group is identified by a user ID, just like a single user, but this user ID is granted the permission to have members.

DBA, RESOURCE, and GROUP permissions

When permissions on tables, views, and procedures are granted to or revoked from a group, all members of the group inherit those changes. The DBA, RESOURCE, and GROUP permissions are not inherited: they must be assigned individually to each individual user ID requiring them.

A group is simply a user ID with special permissions. Granting permissions to a group and revoking permissions from a group are done in exactly the same manner as any other user, using the commands described in "Managing individual user IDs and permissions".

A group can also be a member of a group. A hierarchy of groups may be constructed, each inheriting permissions from its parent group.

A user ID may be granted membership in 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 signing on using the group user ID. This security feature is discussed in "Groups without passwords".

 Creating groups

 Granting group membership to users

 Permissions of groups

 Referring to tables owned by groups

 Groups without passwords

 Special groups


Creating groups
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

Managing groups

Creating groups

 To create a group with name personnel and password group_password:

1	Connect to the database as a user with DBA authority.

2	Create the group's user ID just as you would any other user ID, using the following SQL statement:

GRANT CONNECT

TO personnel

IDENTIFIED BY group_password

3	Give the personnel user ID the permission to have members, with the following SQL statement:

GRANT GROUP TO personnel

The GROUP permission, which gives the user ID the ability to have members, is not inherited by members of a group. If this were not the case, then every user ID would automatically be a group as a consequence of membership in the special PUBLIC group.

Creating groups in Sybase Central

 To create a group in Sybase Central:

1	Connect to the database.

2	Click the Users and Groups folder for that database.

3	Double-click Add Group. A Wizard is displayed, which leads you through the process.

For  more information, see the Sybase Central online Help.


Granting group membership to users
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

Managing groups

Granting group membership to users

Making a user a member of a group is done with the GRANT statement. Membership in a group can be granted either by the DBA or by the group user ID. You can grant user M_Haneef membership in a group personnel as follows:

♦	Connect to the database as a user with DBA authority, or as the group user ID personnel.

♦	Grant membership in the group to M_Haneef with the following SQL statement:

GRANT MEMBERSHIP IN GROUP personnel

TO M_Haneef

When a user is assigned membership in a group, they inherit all the permissions on tables, views, and procedures associated with that group.

Adding users to groups in Sybase Central

One way to add a user to a group in Sybase Central is as follows:

♦	Connect to the database.

♦	Double-click the Users and Groups folder for that database to open it. Groups are displayed in the left panel, and both users and groups are displayed in the right panel.

♦	In the right panel, select the users you want to add to a group, and drag them to the group.

For more information, see the Sybase Central online Help.


Permissions of groups
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

Managing groups

Permissions of groups

Permissions may be granted to groups in exactly the same way as to any other user ID, and permissions on tables, views, and procedures are inherited by members of the group, including other groups and their members. There are some complexities to group permissions that database administrators need to keep in mind.

Notes

The DBA, RESOURCE, and GROUP permissions are not inherited by the members of a group. Even if the personnel user ID is granted RESOURCE permissions, the members of personnel do not have RESOURCE permissions.

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. If, however, SELECT authority is explicitly granted to the personnel user ID by the DBA or by the personnel user ID itself, all group members do have select access to the table. In other words, only granted permissions are inherited.


Referring to tables owned by groups
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

Managing groups

Referring to tables owned by groups

Groups are used for finding tables and procedures in the database. For example, the query

SELECT * FROM SYSGROUPS

will always find the table SYSGROUPS, because all users belong to the PUBLIC group and PUBLIC belongs to the SYS group which owns the SYSGROUPS table. (The SYSGROUPS table contains a list of group_name, member_name pairs representing the group memberships in your database.)

If a table employees is owned by the personnel user ID, 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

It is advisable that you 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. This allows everyone to access the tables without qualifying names. You can then create permission groups and grant users membership in these permission groups as warranted. For an example of this, see the section "Database object names and prefixes".


Groups without passwords
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

Managing groups

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 all handling of groups and their database objects is done by the DBA, rather than permitting other user IDs to make changes to group membership.

This is done by explicitly disallowing connection as the group's user ID when creating the group. To do this, the GRANT CONNECT statement is typed 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, but 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. This assignment of ownership can be carried out only by the DBA.


Special groups
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

Managing groups

Special groups

When a database is created, two groups are also automatically created. These are SYS and PUBLIC. Neither of these groups has passwords, so it is not possible to connect to the database as either SYS or as PUBLIC. The two groups serve important functions in the database.

The SYS group

The SYS group is owner of 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 a description of the system tables and views, together with a description of access to the tables, see the chapters "SQL Anywhere System Tables" and "SQL Anywhere System Views".

The PUBLIC group

When a database is created, the PUBLIC group is automatically created, with CONNECT permissions to the database and SELECT permission on the system tables.

The PUBLIC group is a member of the SYS group, and has read access for some of the system tables and views, so that 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.


Database object names and prefixes
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

Database object names and prefixes

The name of every database object must be an identifier. The rules for valid identifiers are described in "Watcom-SQL language elements". 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 this case the owner name is enclosed in double quotes, as DBA is a SQL keyword.) 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, view and procedures, and when you do not.

When referring to a database object, a prefix is required 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. All the tables are created by the user ID company. This user ID is used by the database administrator and is therefore given DBA authority.

GRANT CONNECT TO company

IDENTIFIED BY secret;

GRANT DBA TO company;

The tables in the database are created by the company user ID.

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 will now work:

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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

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 information on how to create views, see "Working with views".

 Using views for tailored security

 Using procedures for tailored security


Using views for tailored security
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

Using views and procedures for extra security

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 that 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 provides the information she needs, and grants the appropriate permissions to the sales manager user ID.

The first example gives the sales manager permission to see the employees in the Sales department by defining a view on the employee table.

♦	Create the new user ID using the GRANT command, from a user ID with DBA authority. Enter the following:

CONNECT "dba" IDENTIFIED by sql ;

GRANT CONNECT TO SalesManager IDENTIFIED BY sales

 (You must enclose DBA in quotation marks because it is a SQL keyword, just like SELECT and FROM.)

♦	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 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.

♦	Give SalesManager permission to look at the view: GRANT SELECT ON emp_sales TO SalesManager Exactly the same command is used to grant permission on a view as to grant permission on a table.

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:

♦	Create the view.

CREATE VIEW order_summary AS

SELECT order_date, region, sales_rep, company_name

FROM "dba".sales_order

   KEY JOIN "dba".customer

♦	Grant permission for the Sales Manager to examine this view.

GRANT SELECT

ON order_summary

TO SalesManager

♦	To check that the process has worked properly, connect to the SalesManager user ID and look at the views you have 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

Update permissions on views

The example shows how to use views to tailor SELECT permissions. INSERT, DELETE, and UPDATE permissions can also be granted on views.

For information on allowing data modification on views, see "Using views".


Using procedures for tailored security
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

Using views and procedures for extra security

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. With this approach, the manner in which data in the database can be modified is strictly defined.

Stored procedures—Stored procedures are not supported by the SQL Anywhere Desktop Runtime system.


How SQL Anywhere assesses user permissions
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

How SQL Anywhere assesses user permissions

Groups do introduce complexities in the permissions of individual users. Suppose user M_Haneef has been granted select and update permissions on a specific table individually, but is also a member of two groups, one of which has no access to the table at all, and one of which has only select access. What are the permissions in effect for this user?

SQL Anywhere decides whether a user ID has permission to carry out a specific action in the following manner:

♦	SQL Anywhere looks to see if the user ID has DBA permissions: if so, the user ID can carry out any action in the database.

♦	If the user ID does not have DBA permissions, SQL Anywhere looks at the permissions assigned to the individual user. If the user ID has been granted permission to carry out the action, then the action is allowed to proceed.

♦	If no individual settings have been made for that user, SQL Anywhere looks at the permissions of each of the groups of which the user is a member. If any of these groups has permission to carry out the action, then the user ID has permission by virtue of membership in that group, and the action is allowed to proceed.

This approach minimizes problems associated with the order in which permissions are set.


Users and permissions in the system tables
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 24. Managing User IDs and Permissions

Users and permissions in the system tables

Information about the current users of a database and about their permissions is stored in the database system tables and system views.

For a description of each of these tables, see "SQL Anywhere System Tables".

The system tables are owned by the special user ID SYS. It is not possible to connect to 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 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. All permissions and group memberships set up in a new database for SYS, PUBLIC, and DBA can be fully modified.

The following table summarizes the system tables containing information about user IDs, groups, and permissions. All tables and views are owned by user ID SYS, 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 command s
SYSCOLPERM	PUBLIC	All columns with UPDATE permission given by the GRANT command
SYSDUMMY	PUBLIC	Dummy table, 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
SYSYUSERPERMS	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 tables and views, there are tables and views containing information about each of the objects of the database that include the owner of each object.


Backup and Data Recovery
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 25. Backup and Data Recovery

About this chapter

This chapter explains how to use SQL Anywhere transaction log files to protect your data, how to make backup copies of your database files and the SQL Anywhere logs, and the recovery procedures for system and media failures.

 System and media failures

 The SQL Anywhere logs

 Using a transaction log mirror

 Backing up your database

 Recovery from system failure

 Recovery from media failure


System and media failures
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 25. Backup and Data Recovery

System and media failures

SQL Anywhere has features to protect your data from two categories of computer failure: system failure and media failure.

System Failure   A system failure occurs when a power failure or some other failure causes the computer or operating system to go down while there are partially completed transactions. This could occur when the computer is inappropriately turned off or rebooted, or when another application causes the operating system to crash.

Media Failure   A media failure occurs when the database file, the file system, or the device storing the database file becomes unusable.

Recovery from failure

When failures occur, the SQL Anywhere recovery mechanism treats transactions properly, as atomic units of work: any incomplete transaction is rolled back and any committed transaction is preserved. This ensures that even in the event of failure, the data in your database remains in a consistent state.

SQL Anywhere uses three logs to protect your data from system. These log files exist for each database running on a database engine or server.

Make regular backups

You should make regular backups of your database files so that you can recover your database in the case of a media failure. SQL Anywhere uses the transaction log (which you should store on a separate device from the database for greater security) to recover information put into the database since the last full backup.

The SQL Anywhere Desktop Runtime database engine does not support a transaction log, so the work carried out between the time of the last backup and the time of the media failure is lost, and you will have to re-enter it into the database.


The SQL Anywhere logs
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 25. Backup and Data Recovery

The SQL Anywhere logs

SQL Anywhere uses three logs to protect your data from system and media failure.

♦	"The checkpoint log"

♦	"The rollback log"

♦	"The transaction log"

All these logs play a role in data recovery. Each log exists for each database running on a database engine or server. Optionally, you can maintain a mirror of the transaction log for greater protection of vital data.

 The checkpoint log

 The rollback log

 The transaction log

 Converting transaction logs to SQL


The checkpoint log
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 25. Backup and Data Recovery

The SQL Anywhere logs

The checkpoint log

Checkpoint log purpose

The checkpoint log is used during database recovery after a system failure or improper shutdown of the database engine.

A SQL Anywhere database file is composed of pages. Before a page is updated (made dirty), a copy of the original is always made. The copied pages are the checkpoint log.

Dirty pages are not written immediately to the disk. For improved performance, they are cached in memory and written to disk when the cache is full or the server has no pending requests. A checkpoint is a point at which all dirty pages are written to disk. Once all dirty pages are written to disk, the checkpoint log is deleted.

Reasons for a checkpoint

A checkpoint can occur for several reasons:

♦	The database engine is shut down

♦	The amount of time since the last checkpoint exceeds the database option CHECKPOINT_TIME

♦	The estimated time to do a recovery operation exceeds the database option RECOVERY_TIME

♦	The database engine is idle long enough to write all dirty pages

♦	A transaction issues a CHECKPOINT statement

♦	The database engine is running without a transaction log and a transaction is committed

 Checkpoint priority

 How the database decides when to checkpoint


Checkpoint priority
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 25. Backup and Data Recovery

The SQL Anywhere logs

The checkpoint log

Checkpoint priority

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 database option CHECKPOINT_TIME controls the maximum desired time, in minutes, between checkpoints.

♦	Recovery Urgency   A heuristic to estimate the amount of time required to recover the database if it fails right now. The database option RECOVERY_TIME controls the maximum desired time, in minutes, for recovery in the event of system failure.

The checkpoint and recovery urgencies are important when the database engine does not have enough idle time to write dirty pages.

When the database server is running with multiple databases, the CHECKPOINT_TIME and RECOVERY_TIME specified by the first database started is used, unless overridden by command line switches.

For a description of the command-line options, see "The database engine".


How the database decides when to checkpoint
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 25. Backup and Data Recovery

The SQL Anywhere logs

The checkpoint log

How the database decides when to checkpoint

Optional information—You do not need to know the information in this section for most purposes. It is provided as background information for those who wish to understand more about how the database engine works.

The idle I/O task

The writing of dirty pages to disk is carried out by a task within the database engine called the idle I/O task. This task shares processing time with other database tasks, according to a priority. The lower the priority of the idle I/O task, the less time it gets.

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 is increased. At intervals, the priority is increased again. As the urgency becomes high, the engine shifts its primary focus to writing dirty pages until the number gets below the threshold again. However, the engine 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.


The rollback log
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 25. Backup and Data Recovery

The SQL Anywhere logs

The rollback log

As changes are made to the contents of tables, a rollback log is kept for the purpose of canceling changes. It is used to process the ROLLBACK statement for recovering from system failure. There is a separate rollback log for each transaction. When a transaction is complete, its rollback log is deleted.


The transaction log
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 25. Backup and Data Recovery

The SQL Anywhere logs

The transaction log

All changes to the database are stored in the transaction log in the order that they occur. Inserts, updates, deletes, commits, rollbacks, and database schema changes are all logged. The transaction log is called a forward log file.

What you should do

The transaction log is optional. If you run SQL Anywhere with no transaction log, a checkpoint is carried out whenever a transaction is committed. The checkpoint ensures that all committed transactions are written to the disk. Checkpoints can be time consuming, so you should run with a transaction log for improved performance as well as protection against media failure and corrupted databases.

For greater protection, SQL Anywhere allows you to maintain two identical transaction logs in tandem. This is called transaction log mirroring.

For information on creating a database with a mirrored transaction log, see "The Initializ ation utility". For information on changing an existing database to use a mirrored transaction log, see "The Transaction Log utility".

Keep the transaction log on a separate device

The transaction log is not kept in the main database file. The filename of the transaction log can be set when the database is initialized (with DBINIT) or at any other time (with DBLOG) when the database engine is not running. To protect against media failure, the transaction log should be written to a different device than the database file. Some machines with two or more hard drives only have one physical disk drive with several logical drives or partitions. If you want protection against media failure, make sure that you have a machine with two storage devices or use a storage device on a network file server. Note that by default, the transaction log is put on the same device and in the same directory as the database—this does not protect against media failure.

Primary key definitions affect transaction log size

Updates and deletes on tables that do not have a primary key or unique index will cause the entire contents of the rows affected to be logged in the transaction log. If a primary key is defined, the engine needs only to record the primary key column values to uniquely identify a row. If the table contains many columns or wide columns, the transaction log pages will fill up much faster (reducing performance) if no primary key is defined. And  if DBTRAN is used on the transaction log, it produces a very large command file.

This affects UPDATEs and DELETEs but not INSERTs, which must always log all column values.

If a primary key does not exist, the engine will look for a UNIQUE NOT NULL index on the table (or a UNIQUE constraint). A UNIQUE index that allows null values is not sufficient.

Performance tip—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.


Converting transaction logs to SQL
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 25. Backup and Data Recovery

The SQL Anywhere logs

Converting transaction logs to SQL

The transaction log is not human-readable. The command-line utility DBTRAN can be used to convert a transaction log into a SQL command file, which can serve as an audit trail of changes made to the database. The following command uses DBTRAN to convert a transaction log:

dbtran sample.log changes.sql

You can also convert a transaction log to a SQL command file from Sybase Central or from ISQL.

For more information on the log translation utility, see "The Log Translation utility".

Recovering uncommitted database changes

The transaction log contains a record of everything, including transactions that were never committed. By converting the transaction log to a SQL command file using the log translation utility and choosing to include uncommitted transactions (for example by running the DBTRAN command-line utility with the -a switch) you can recover transactions that were accidentally canceled by a user. (If this option is not chosen, the log translation utility omits transactions that were rolled back.) While this is not a common procedure, it can prove useful for exceptional cases.


Using a transaction log mirror
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 25. Backup and Data Recovery

Using a transaction log mirror

A transaction log mirror is an identical copy of the transaction log, maintained at the same time as the transaction log. Transaction log mirrors are used to allow complete recovery in the case of media failure on the log device.

Every time a database change is written to the transaction log, it is also written to the transaction log mirror file. By default, SQL Anywhere does not use a mirrored transaction log, but you can choose to use one when creating a database or you can make an existing database use a mirrored transaction log.

Why use a transaction log mirror?

A mirrored transaction log provides extra protection of critical data. 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.

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.

If SQL Anywhere is using a mirrored transaction log, and gets an error while trying to write to one of them (for example, if the disk is full), the database engine or 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 SQL Anywhere continued with a single log.

Where to use a transaction log mirror

A transaction log mirror 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.

Requirements

You can only use a mirrored transaction log on a database created with SQL Anywhere Release 5.0 or later.

 Creating and dropping a transaction log mirror

 Erasing transaction log mirrors

 Validating the transaction log on database startup

 Recovering from a corrupt transaction log or mirror


Creating and dropping a transaction log mirror
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 25. Backup and Data Recovery

Using a transaction log mirror

Creating and dropping a transaction log mirror

Transaction log mirrors can be created at the following times:

♦	When you create a database, using the initialization utility

♦	At any other time that the database is not running, using the transaction log utility.

♦	A mirror for a write file transaction log can be created along with the write file using the write file utility (mirroring can be added later, using the transaction log utility)

Notes

♦	You cannot choose to use a transaction log mirror without using a transaction log

♦	The default file extension for transaction log mirrors is .MLG.

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 Sybase Central or from the DBINIT command-line utility.

From Sybase Central, the transaction log mirror option is part of the Create Database utility.

For more information, see the Sybase Central online Help.

The following command line (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 different device still.

dbinit -t d:\log_dir\company.log -m e:\mirr_dir\company.mlg c:\db_dir\company.db

By default, a transaction log is used but no transaction log mirror is created. For a full description of DBINIT command-line options, see "Initialization utility options".

Starting a transaction log mirror for an existing database

You can choose to maintain a transaction log mirror for an existing database any time the database is not running by using the transaction log utility. This option is available from either Sybase Central or the DBLOG command-line utility.

From Sybase Central, the transaction log mirror option is part of the Change Log File utility.

For more information, see the Sybase Central online Help.

The following command line starts a transaction log mirror for a database named company.db, which is already using one transaction log.

dblog -m e:\mirr_dir\company.mlg c:\db_dir\company.db

The following command line stops the company.db database from using a transaction log mirror, but continues maintaining a transaction log:

dblog -r c:\db_dir\company.db

The following command line stops the company.db database from using a transaction log mirror or a transaction log:

dblog -n c:\db_dir\company.db

With the transaction log utility you can also alter the name or directory of the transaction log and mirror. For a full description of DBLOG command-line options, see "Transaction log utility options".

Starting a transaction log mirror for a write file

You can choose to maintain a transaction log mirror for a write file when you create the write file using the write file utility, or at a later time using the transaction log utility.

The option to create a transaction log mirror when creating a write file is available from Sybase Central or from the DBWRITE command-line utility.

From Sybase Central, the transaction log mirror option is part of the Create Write File utility.

For more information, see the Sybase Central online Help.

The following command line (which should be entered on one line) creates a write file for a database named company.db, which is already using a transaction log. The write file has default extension .WRT, the write file transaction log has the default extension .WLG, and the write file transaction log mirror has the default extension .WML.

dbwrite -c -t d:\log_dir\company.wlg -m e:\mirr_dir\company.wml c:\db_dir\company.db c:\db_dir\company.wrt

For a full description of DBWRITE command-line options, see "Write file utility options".

You can change the transaction log and log mirror settings of a write file using the transaction log utility, in exactly the same way as described above for a standard database file.


Erasing transaction log mirrors
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 25. Backup and Data Recovery

Using a transaction log mirror

Erasing transaction log mirrors

You can erase transaction log mirrors using the Erase utility in Sybase Central or the DBERASE command-line utility.

The Erase utility is available in Sybase Central as the Erase Database utility or from the command line as the DBERASE utility.

 To delete a mirror log file only:

1	Enter the following command:

dberase e:\mirr_dir\company.wml

 To delete a transaction log file but not its mirror:

1	Enter the following command:

dberase e:\log_dir\company.log


Validating the transaction log on database startup
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 25. Backup and Data Recovery

Using a transaction log mirror

Validating the transaction log on database startup

When a database that is using a mirror starts up, the database engine or server carries out a series of checks and automatic recovery operations to confirm that the transaction log and its mirror are not corrupted, and to correct some problems if corruption is detected.

On startup, the database engine 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 when you are maintaining a log mirror.

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 database engine finds that the transaction log and the mirror are identical up to the end of the shorter of the two files, then the remainder of the longer file is copied over into the shorter file to produce identical log and mirror. After this automatic recovery step, the database engine 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.


Recovering from a corrupt transaction log or mirror
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 25. Backup and Data Recovery

Using a transaction log mirror

Recovering from a corrupt transaction log or mirror

When a database engine or server detects a difference between the transaction log and its mirror in the body of the file, the engine does not start. You must take the following steps before starting the engine:

♦	Identify which of the two files is corrupt.

♦	Copy the correct file over the corrupt file so that you have two identical files again.

♦	Restart the database engine.

When a database engine detects a difference between the transaction log and its mirror, it has no means of knowing which is intact and which is corrupt.

 To identify which file is corrupt using the database utilities:

1	Make a copy of the backup of your database file taken at the time the transaction log was started.

2	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 command-line utility.)

3	The following command-line translates a transaction log named SADEMO.LOG, placing the translated output into SADEMO.SQL:

dbtran sademo.log

The translation utility properly translates the intact file, and will report an error while translating the corrupt file.

4	If the DBTRAN test does not identify the incorrect log, you may want to compare the two translated logs (SQL files) to see which one contains an error, or use a disk utility to inspect the two files and detect which is corrupt.

5	Once you have identified the corrupt file, you can copy the intact log file over the corrupt file, and restart the production database engine.


Backing up your database
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 25. Backup and Data Recovery

Backing up your database

A full backup makes a copy of the database file and (optionally) a copy of the transaction log. Full backups are described in "Performing a full backup".

An incremental backup makes a copy of the transaction log.

Both full and incremental backups can be carried out online or offline. You can use any means of backing up the files onto diskette, magnetic tape, optical disk, or any other device. Incremental backups are described in "Performing an incremental backup".

Online backups

Backups can be made without stopping the database engine. The backup utility can be run against a standalone engine or network database server. Using the backup utility on a running database is equivalent to copying the database files when the database is not running. In other words, it provides a snapshot of a consistent database, even while it is being modified by other users.

For a full description of the online backup facility, see "The Backup utility".

Offline backups

The database engine should not be running when you do offline backups by copying database files. Moreover, it should be taken down cleanly.

If you are running a multiuser database, you can use the database server -t command line option to shut down at a specified time. This way, you can have your offline backup procedure start late at night automatically.

 Performing a full backup

 Performing an incremental backup


Performing a full backup
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 25. Backup and Data Recovery

Backing up your database

Performing a full backup

Check the validity of the database

Before doing a full backup, it is a good idea to verify that the database file is not corrupt. File system errors or software errors (bugs) in any software you are running on your machine could corrupt a small portion of the database file without you ever knowing.

With the database engine running on the database you want to check, execute the validation utility that comes with SQL Anywhere. For example, you could run the DBVALID command-line utility:

dbvalid -c "uid=dba;pwd=sql"

You can also run the validation utility from Sybase Central or ISQL.

The validation utility scans every record in every table and looks up each record in each index on the table. If the database file is corrupt, you need to recover from your previous backup.

For more information on running the validation utility, see "The Validation utility".

Back up the database files

A full backup is completed offline by copying the database file(s) and optionally the transaction log to the backup media. A full backup should be completed according to a regular schedule that you follow carefully. Once a week works well for most situations.

To do a backup while the database engine is running, you use the backup utility. You require DBA authority in order to run the backup utility on a database. The backup utility can be run from Sybase Central, ISQL, or using the DBBACKUP command-line utility.

For more information, see "The Backup utility".

For example, you could carry out a full backup of the sample database, held in C:\SQLANY50\SADEMO.DB, to a directory E:\BACKUP, using user ID dba, and password sql.

 To complete a full backup:

1	Enter the following command line:

dbbackup -c "uid=dba;pwd=sql;

dbf=c:\sqlany50\sademo.db" e:\backup

As neither of -d or -t is specified, both the database files and transaction log are backed up.

Transaction log options

Whenever the database file is backed up, the transaction log can be archived and/or deleted (use the Erase utility). Provided the backup can be restored, you will never need the transaction log. Archiving transaction logs provides you with a history of all changes to your database and also provides protection if you are unable to restore the most recent full backup. The backup utility has command line options to delete and restart the transaction log (DBBACKUP -x) or backup and restart the transaction log (DBBACKUP -r) while the database engine is running.

Keep several full backups

You should keep several previous full backups. If you back up on top of the previous backup, and you get a media failure in the middle of the backup, you are left with no backup at all. You should also keep some of your full backups offsite to protect against fire, flood, earthquake, theft, or vandalism.

If your transaction log tends to grow to an unmanageable size between full backups, you should consider getting a larger storage device or doing full backups more frequently.


Performing an incremental backup
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 25. Backup and Data Recovery

Backing up your database

Performing an incremental backup

An incremental backup is a copy of the transaction log. The transaction log has all changes since the most recent full backup.

You can carry out an offline incremental backup by making a copy of the transaction log file. Alternatively, you can carry out an online incremental backup by running the backup utility and backing up just the transaction log. You can do this from the command line using the DBBACKUP utility with the -t switch, or you can use the backup utility from Sybase Central or ISQL. You require DBA authority in order to run the backup utility on a database file.

For example, you could carry out an incremental backup of the sample database, held in C:\SQLANY50\SADEMO\DB, to a directory E:\BACKUP, with user ID dba, and password sql.

 To complete an incremental backup:

1	Enter the following command line:

dbbackup -c "uid=dba;pwd=sql; dbf=c:\sqlany50\sademo.db" -t e:\backup

Daily backups of the transaction log

You should back up the transaction log daily. This is particularly important if you have the transaction log on the same device as the database file. If you get a media failure, you could lose both files. By doing daily backups of the transaction log, you will never lose more than one day of changes.

Daily backups of the transaction log are also recommended when the transaction log tends to grow to an unmanageable size between full backups and you do not want to get a larger storage device or do more frequent full backups. In this case, you can choose to archive and delete the transaction log.

There is a drawback to deleting the transaction log after a daily backup. If you have media failure on the database file, there will be several transaction logs since the last full backup. Each of the transaction logs needs to be applied in sequence to bring the database up to date.

For a description of how to do this, see "Media failure on the database file".


Recovery from system failure
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 25. Backup and Data Recovery

Recovery from system failure

After a power failure or other system failure you should run the system disk verification program:

♦	For OS/2: Run scandisk with the /autofix option.

♦	For NetWare: Load the Novell VREPAIR NLM to repair any volume that will not mount due to errors.

♦	For QNX: Use chkfsys.

♦	For DOS or Windows NT, run the DOS or NT console command:

chkdsk /f

This command fixes simple errors in the file system structure that might have been caused by the system failure. This should be done before running any software, including Windows if applicable.

This fixes up simple errors in the file system structure that might have been caused by the system failure. This should be done before running any other software.

After a system error occurs, SQL Anywhere automatically recovers when you restart 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. It is possible to recover uncommitted changes manually (see "Recovering uncommitted changes").

Steps to recover from a system failure

The database engine automatically takes three steps to recover from a system failure:

♦	Restore all pages to the most recent checkpoint, using the checkpoint log.

♦	Apply any changes made between the checkpoint and the system failure. These changes are in the transaction log.

♦	Rollback all uncommitted transactions, using the rollback logs. There is a separate rollback log for every connection.

Frequent checkpoints make recovery from system failure take less time but also create work for the database engine writing out dirty pages.

There are two database options that allow you to control the frequency of checkpoints. CHECKPOINT_TIME will control the maximum desired time between checkpoints and RECOVERY_TIME will control the maximum desired time for recovery in the event of system failure (see "SET OPTION statement"). The RECOVERY_TIME specifies an estimate for steps 1 and 2 only.

Step 3 may take a long time if there are long uncommitted transactions that have already done a great deal of work before the last checkpoint.

The transaction log is optional. When you are running SQL Anywhere with no transaction log, a checkpoint is done whenever any transaction is committed. In the event of system failure, the database engine uses steps 1 and 3 from above to recover a database file. Step 2 is not necessary because there will be no committed transactions since the last checkpoint. This is, however, usually a slower way to run because of the frequent checkpoints.

Runtime engine is an exception—The SQL Anywhere Runtime System does not employ a transaction log.

 Quick recovery with a live backup


Quick recovery with a live backup
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 25. Backup and Data Recovery

Recovery from system failure

Quick recovery with a live backup

You can carry out a live backup of the transaction log by using the DBBACKUP command line utility with the -l command-line option.

Live backups provide a redundant copy of the transaction log that is available for restart of your system in case of system failure. 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.


Recovery from media failure
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 25. Backup and Data Recovery

Recovery from media failure

If you have backups, you can always recover all transactions that were committed before the media failure. Recovery from media failure requires you to keep the transaction log on a separate device from the database file. The information in the two files is redundant. Regular backups of the database file and the transaction log reduce the time required to recover from media failures.

The first step in recovering from a media failure is to clean up, reformat, or replace the device that failed.

The steps to take in recovery depend on whether the media failure is on the device holding your database file (see "Media failure on the database file") or on the device holding your transaction log (see "Media failure on the transaction log").

 Media failure on the database file

 Media failure on the transaction log

 Recovering uncommitted changes


Media failure on the database file
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 25. Backup and Data Recovery

Recovery from media failure

Media failure on the database file

When your transaction log is still usable, but you have lost your database file, the recovery process depends on whether you keep or delete the transaction log on incremental backup.

If you have a single transaction log

If you have not deleted or restarted the transaction log since the last full backup, the transaction log contains everything since the last backup. Recovery involves four steps:

♦	Make a backup of the transaction log immediately. The database file is gone and the only record of the changes is in the transaction log.

♦	Restore the most recent full backup (the database file).

♦	Use the database engine with the apply transaction log (-a) switch, to apply the transaction log and bring the database up to date:

DBENG50 sademo.db -a sademo.log

♦	Start the database in the normal way. The database engine will come up normally and any new activity will be appended to the current transaction log.

If you have multiple transaction logs

If you have archived and deleted the transaction log since the last full backup, each transaction log since the full backup needs to be applied in sequence to bring the database up to date.

♦	Make a backup of all transaction logs immediately. The database file is gone and the only record of the changes is in the transaction logs.

♦	Restore the most recent full backup (the database file).

♦	Starting with the first transaction log after the full backup, apply each archived transaction log by starting the database engine with the apply transaction log (-a) switch. For example, if the last full backup was on Sunday and the database file is lost during the day on Thursday.

DBENG50W sademo.db -a mon.log

DBENG50W sademo.db -a tue.log

DBENG50W sademo.db -a wed.log

DBENG50W sademo.db -a sample.log

♦	SQL Anywhere does not allow you to apply the transaction logs in the wrong order or to skip a transaction log in the sequence.

♦	Start the database in the normal way. The database engine will come up normally and any new activity will be appended to the current transaction log.


Media failure on the transaction log
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 25. Backup and Data Recovery

Recovery from media failure

Media failure on the transaction log

When your database file is still usable but you have lost your transaction log, the recovery process is as follows:

♦	Make a backup of the database file immediately. The transaction log is gone and the only record of the changes is in the database file.

♦	Restart the database with the -f switch.

DBENG50 sademo.db -f

Without the switch, the database engine will complain about the lack of a transaction log. With the switch, the database engine will restore the database to the most recent checkpoint and then roll back any transactions that were not committed at the time of the checkpoint. A new transaction log will be created.

Consequences of media failure on the transaction log

Media failure on the transaction log can have more serious consequences than media failure on the database file. When you lose the transaction log, all changes since the last checkpoint are lost. This will be a problem when you have a system failure and a media failure at the same time (such as if a power failure causes a head crash that damages the disk). Frequent checkpoints minimize the potential for lost data, but also create work for the database engine writing out dirty pages.

For running high-volume or extremely critical applications, you can protect against media failure on the transaction log by mirroring the transaction log or by using a special-purpose device, such as a storage device that mirrors the transaction log automatically. If you are using the SQL Anywhere Server for NetWare, NetWare allows you to automatically mirror a NetWare volume.

For information on using a transaction log mirror, see "Using a transaction log mirror".


Recovering uncommitted changes
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 25. Backup and Data Recovery

Recovery from media failure

Recovering uncommitted changes

The transaction log keeps a record of all changes made to the database. Even uncommitted changes are stored in the transaction log. The DBTRAN utility has a command line option (-a) to translate transactions that were not committed. With this option, you can recover changes that were not committed by editing the SQL command file and picking out changes that you want to recover.

Changes not present in the transaction log—The transaction log may contain changes right up to the point where a failure occurred. It will contain any changes that were made before the most recent COMMIT by any transaction.


Introduction to SQL Remote Replication
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

About this chapter

SQL Remote is a message-based replication system for two-way server-to-laptop, server-to-desktop, and server-to-server data replication between SQL Anywhere databases.

This chapter introduces SQL Remote and guides you through setting up a simple replication system.

 Introduction to data replication

 SQL Remote concepts

 SQL Remote features

 Message systems supported by SQL Remote

 Tutorial: setting up SQL Remote using Sybase Central

 Set up the consolidated database in Sybase Central

 Set up the remote database in Sybase Central

 Tutorial: setting up SQL Remote using ISQL and DBXTRACT

 Set up the consolidated database

 Set up the remote database

 Start replicating data

 A sample publication

 Some sample SQL Remote setups


Introduction to data replication
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

Introduction to data replication

Data replication is the sharing of data among physically distinct databases. Changes made to shared data at any one database are replicated to the other databases in the replication setup. The SQL Remote data replication system enables replication of data among SQL Anywhere databases.

Replication and 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 that you are not cut off from data in the event of a failure of a long-distance network connection.

Replication and performance

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

Replication and integrity

One of the challenges of any replication system is to ensure that each database retains data integrity at all times. Today's replication systems, such as Sybase Replication Server and SQL Remote, replicate portions of the transaction log in such a way that transactions are replicated atomically: either a whole transaction is replicated, or none of it is replicated. This ensures data integrity at each database in the setup.

Replication and data consistency

Another challenge to replication systems is to maintain data consistency throughout the setup. SQL Anywhere and other 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 because of the time lag different sites may have different copies of data at any instant.

Replication with SQL Anywhere

SQL Anywhere supports two forms of replication. SQL Anywhere databases can take part in Sybase Replication Server setups. Replication Server is a powerful, high-performance, technology for maintaining replicated data at multiple sites on a network. Replication Server permits replication among heterogeneous databases and database management systems. Replication Server can replicate data to SQL Anywhere databases using the Open Server Gateway that is part of this package. To replicate data from SQL Anywhere databases to other databases using Replication Server, you need a SQL Anywhere Replication Agent, which is available as a separate product.

SQL Remote is a system for data replication between SQL Anywhere databases only. SQL Remote is less flexible and configurable than Replication Server; for example, it has strict requirements for object names and attributes to be identical at different databases in the replication setup. Rather, SQL Remote is designed to be easy to administer, suitable for widespread deployment, capable of supporting replication to many replicate sites from one database, and is designed to replicate data even between databases not directly connected to each other. The following sections describe SQL Remote in more detail.


SQL Remote concepts
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

SQL Remote concepts

This section introduces concepts and terms used throughout the chapter.

 Consolidated and remote databases

 Message-based replication

 The Message Agent

 Publications and subscriptions

 Remote database users


Consolidated and remote databases
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

SQL Remote concepts

Consolidated and remote databases

SQL Remote provides data replication between a consolidated database and a remote database or databases. Remote databases are SQL Anywhere servers or standalone database engines that may be running at the same site as the consolidated database or at different sites. Stated another way, SQL Remote supports hierarchical configurations of databases; it does not support peer-to-peer replication or other non-hierarchical configurations.

The consolidated database contains all the data to be replicated. Remote databases may contain all the data or may contain just some of the data. Replication is two-way: changes made at the consolidated database are replicated to remote databases, while changes made at remote databases are replicated to the consolidated database, and thence to other remote databases.

With a hierarchy constructed in this way, each database contains all or a subset of the data replicated by the node 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.


Message-based replication
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

SQL Remote concepts

Message-based replication

SQL Remote exchanges data between databases using messages. This allows replication between databases that have no direct connection: an occasional message-based connection such as e-mail is sufficient.

In message-based communications, each message carries its destination address and other control information, so that no direct connection is needed between applications exchanging information. E-mail is one example of message-based communications.

Just as session-based client/server applications rely on network communication protocol stacks, such as TCP/IP or Novell NetWare's IPX, so message-based applications rely on message services such as Microsoft's Messaging API (MAPI), Lotus' Vendor Independent Messaging (VIM), Internet Simple Mail Transfer Protocol (SMTP) or a 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.

Unlike some session-based communications, many message-based systems do not guarantee that messages reach their destination, or that messages are received in the same order they were sent. SQL Remote incorporates a protocol to guarantee reception of replication updates in the correct order.

Building a replication system on top of a message system means that 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. Each computer involved in a setup must have a message system client installed, and they exchange information through the message system.


The Message Agent
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

SQL Remote concepts

The Message Agent

The SQL Remote technology is contained partly in the SQL Anywhere database engine and partly in the Message Agent. The Message Agent is a client application that sends and receives messages from database to database. The Message Agent is a program called DBREMOTE, and it must be installed at both the consolidated and at the remote sites.


Publications and subscriptions
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

SQL Remote concepts

Publications and subscriptions

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.

Data is organized into publications

A publication may include data from several 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.

Periodically, the changes made to each publication in a database are replicated to all subscribers to that publication. These replications are called publication updates.

Each end of the replication needs a publication and a subscription

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, but remote databases also send messages to the consolidated database.

For example, if data in a publication at the remote database is updated, those updates must be sent to the consolidated database. Even if the publication is never updated at the remote database, the remote database sends confirmation messages back to the consolidated database, to keep track of the status of the replication. 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 an identical publication created at the remote database.

When remote database users modify their own copies of the data, their changes are replicated to the consolidated database. When the replication is made successfully 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.

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 from Sybase Central or as a command-line utility.

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.


Remote database users
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

SQL Remote concepts

Remote database users

A replication setup includes many copies of the information in a database. While each replicate is a physically separate database on a separate computer, whether it be a sales representative's laptop computer or an office database on a server, all must stay consistent with the consolidated database. The entire replication setup may be considered a single database, with the master copy of all 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 multiuser server, the entire site is considered to be a single remote user of the consolidated database.


SQL Remote features
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

SQL Remote features

The following features are key to SQL Remote's design.

 Transaction log-based replication

 Central administration

 Support for many subscribers

 Economical resource requirements


Transaction log-based replication
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

SQL Remote features

Transaction log-based replication

SQL Remote replication is based on the transaction log, enabling it to replicate only changes to data, rather than all data, in each update.

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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

SQL Remote features

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.

  For more information

For information on administering remote users, see "Granting and revoking REMOTE and CONSOLIDATE permissions".

For information on administering publications, see "Setting up publications".

For information on administering subscriptions, see "Setting up subscriptions".

For information on replication conflicts and their management, see "Error reporting and conflict resolution in SQL Remote".

The passthrough mode is designed for direct intervention at remote databases from the consolidated site, and is described in "Using passthrough mode for administration".

You can carry out many administration tasks from the Sybase Central database management tool.


Support for many subscribers
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

SQL Remote features

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 of sales representatives from a single office database.


Economical resource requirements
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

SQL Remote features

Economical resource requirements

The only software required to run SQL Remote in addition to the SQL Anywhere engine is the Message Agent, which is an executable named DBREMOTE, and a message system. If you use the shared file link, no message system software is required as long as you have access to the directory where the message files are stored.

The Message Agent runs on Windows, DOS, Windows NT, and OS/2 platforms. The DOS Message Agent supports only the shared file link. Any SQL Anywhere server or standalone engine can act as a consolidated or remote database.

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.


Message systems supported by SQL Remote
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

Message systems supported by SQL Remote

The message systems supported by SQL Remote are:

♦	MAPI   Used in e-mail systems, including Microsoft Mail.

♦	FILE   A simple file-sharing protocol.

♦	VIM   Used in e-mail systems such as Lotus cc:Mail and groupware products such as Lotus Notes.

♦	SMTP   Used in Internet e-mail systems.

A database can exchange messages using one or more of the available message systems.

  For information about supported message systems, see "Supported message types".


Tutorial: setting up SQL Remote using Sybase Central
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

Tutorial: setting up SQL Remote using Sybase Central

The following sections are a tutorial describing how to set up a simple SQL Remote replication system 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 is presented in "Tutorial: setting up SQL Remote using ISQL and DBXTRACT", and contains the SQL statements executed behind the scenes by Sybase Central.

In this tutorial you will act as the DBA of the consolidated database, and set up a simple replication system. The simple example is a primitive model for an office "news" system, with a single table containing messages together with the database from which they were sent. The table is replicated in a setup with one consolidated database and one remote database. You can install this example on one computer.

The tutorial takes you through the following steps:

♦	Ensure that the consolidated database site and all remote sites have properly configured message systems.

♦	Add the message type you need to the database.

♦	Add a publisher user ID to the database to identify the source of outgoing messages.

♦	Add a remote user to the database for each remote database in the setup.

♦	Create a publication on the consolidated database.

♦	Create subscriptions for remote users to the publication.

♦	Ensure that each remote user has an initial copy of the data on their database by synchronizing the data.

♦	Configure and run the Message Agent at both consolidated and remote sites.

♦	Start replicating data.

The following sections describe how to carry out each of these steps, apart from the message system installation, which is independent of SQL Anywhere.

 Preparing for the Sybase Central replication tutorial


Preparing for the Sybase Central replication tutorial
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

Tutorial: setting up SQL Remote using Sybase Central

Preparing for the Sybase Central replication tutorial

The following steps prepare you for the replication tutorial:

♦	Create a directory to hold the files you make during this tutorial; for example C:\TUTORIAL.

♦	The tutorial uses two databases: a consolidated database named HQ.DB and a remote database named FIELD.DB. At this point, you should create the hq database with the Create Database utility in Sybase Central:

♦	Start Sybase Central. You will be creating a new database so you do not have to connect to any particular existing database.

♦	Click Database Utilities in the left panel.

♦	Double-click Create Database in the right panel. The Create Database wizard is displayed.

♦	Create a database with filename C:\TUTORIAL\HQ.DB.

♦	You can use the default settings for this database. Make sure you elect to maintain a transaction log. Replication cannot take place without a transaction log.

♦	If you wish to set up the example system using a file-sharing link you must create a subdirectory for each of the two user IDs in the replication system. Create these subdirectories using the following statements at a system command line:

mkdir c:\tutorial\hq

mkdir c:\tutorial\field

♦	If you wish to use a MAPI e-mail system as the message system you must have two e-mail user IDs and addresses available; one for the consolidated database and one for the remote database. In this tutorial these will be MAPI user IDs hq_mapi and field_mapi, with MAPI addresses hq_address and field_address.

♦	Add a table to the consolidated database:

♦	Connect to the hq database from Sybase Central, as user ID DBA:

♦	Click Connect from the Tools Menu.

♦	Enter the user ID DBA and the password SQL, then click More>>.

♦	If the hq database is not running, enter the file name with path in the Database File field. If it is running, enter the name hq in the Database Name field.

♦	Click OK to connect.

♦	Click the Tables folder of the hq database.

♦	Double-click Add Table, enter the name news, and click OK to create the empty table.

♦	Double-click the news table icon, then its Columns folder, and then double-click Add Column.

♦	Enter the column name id on the General tab, and on the Data type tab enter the column type INTEGER. Click Edit, and choose a pre-defined default of AUTOINCREMENT. Uncheck the Column Allows NULL setting so that NULLs are not allowed in this column. Then click OK to create the column.

♦	Double-click Add Column, and enter column name pub, of type CHAR( 30 ) and with a pre-defined default of CURRENT PUBLISHER, not allowing NULL. Click OK to create the column.

♦	Double-click Add Column again, and enter column name text, of type CHAR( 255 ), allowing NULL and with no default setting. Click OK to create the column.

♦	Create a two-column primary key. Select the id and pub columns (in that order), click the right mouse button, and select Add to Primary Key from the popup menu.

The two-column primary key, containing an autoincrementing integer and a user ID column, is a useful form of primary key for many tables involved in replication; inclusion of the CURRENT PUBLISHER column default prevents users at different databases from inserting rows with the same primary key value, which would cause conflicts. The CURRENT PUBLISHER default identifies each row by the database from which it originates. For more information, see "Designing publications".

You are now ready for the rest of the tutorial.


Set up the consolidated database in Sybase Central
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

Set up the consolidated database in Sybase Central

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:

♦	Create a message type to use for replication.

♦	Grant PUBLISH permissions to a user ID to identify the source of outgoing messages.

♦	Grant REMOTE permissions to all user IDs that are to receive messages.

♦	Create a publication describing the data to be replicated.

♦	Create subscriptions describing who is to receive the publication.

You require DBA authority to carry out these tasks.

 Add a SQL Remote message type

 Add the publisher and remote user to the database

 Add publications and subscriptions


Add a SQL Remote message type
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

Set up the consolidated database in Sybase Central

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. Currently, the link must be one of FILE or MAPI. A VIM link and an SMTP/POP link are expected to be available in the first quarter of 1996.

♦	An address for this message link, to identify the source of outgoing messages.

SQL Anywhere databases already have MAPI and FILE message types created, but you need to supply an address for the message type you will use. To add an address to a message type:

♦	Click the SQL Remote folder on the left panel.

♦	Double-click the Message Types folder.

♦	Double-click whichever message type (MAPI or FILE) you are going to use for the tutorial.

♦	Enter a publisher address to provide a return address for remote users. For the file message link, enter C:\TUTORIAL\HQ; the directory you have created to hold messages for the consolidated database. (In a production setup, file addresses are taken relative to the value of the SQLREMOTE environment variable or Directory registry setting, which would have been set to C:\TUTORIAL for this tutorial.) For the MAPI message link, enter the valid MAPI address you are using for the consolidated database.

♦	Click OK to save the message type.


Add the publisher and remote user to the database
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

Set up the consolidated database in Sybase Central

Add the publisher and remote user to the database

In SQL Remote's hierarchical replication system, each database may have zero or one consolidated database immediately above it 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:

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 HQ.DB 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.

♦	Click the Users & Groups folder on the left panel.

♦	Double-click Add User. The New User Wizard is displayed.

♦	Enter the name hq_user, with password hq_pwd, and click Next.

♦	On the next page, ensure that the user is granted Remote DBA authority; this enables the user ID to run the Message Agent. Then click Next.

♦	On the final page, check the box identifying this user ID as the publisher. Then click Finish to create the user.

A database can have only one publisher. You can find out who the publisher is at any time by opening the SQL Remote 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 single-user database engine 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.

You can add a remote user as follows:

♦	Click the SQL Remote folder on the left panel, then click the Remote Users folder on the left panel.

♦	Double-click Add Remote User on the right panel. The New Remote User wizard is displayed.

♦	Create a remote user with name field_user, password field_pwd, message type file, and address field. For the message type and address, select the type (FILE or MAPI) and the corresponding address you are using for this user.

♦	You should ensure that the Send Then Close option is checked. (In many production environments you would not choose Send Then Close, but it is convenient for this tutorial.)

♦	You should ensure that the Remote DBA authority is checked, so that the user can run the Message Agent.

♦	When you have finished all the entries, click Finish to create the remote user.


Add publications and subscriptions
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

Set up the consolidated database in Sybase Central

Add publications and subscriptions

This section describes how to add a publication to a database, and how to add a subscription for that publication to a user. You can add a publication that replicates all rows of the table news as follows:

♦	Click the Publications folder in the SQL Remote folder.

♦	Double-click Add Publication. The Publication Wizard is displayed.

♦	Name the publication pub_news on page one of the Wizard. On page two, click Add Table and select news from the list. Leave the All Columns button selected, press OK, and complete the Wizard to create the publication. This publication is one of the simplest that can be created. Publications can involve multiple tables, and subsets of the rows and columns in tables. These can all be defined using the Publication Wizard.

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.

Add a subscription to the pub_news publication for the remote database user field_user:

♦	Double-click the Publications folder, which is in the SQL Remote folder, so that the pub_news publication is displayed in the left panel.

♦	Click the Remote Users folder so that remote users are displayed in the right panel.

♦	Drag the field_user user from the right panel onto the pub_news publication in the left panel. The Create Subscription window is displayed. You should leave both the Subscribe By and With Value text boxes empty; click OK to create the subscription.


Set up the remote database in Sybase Central
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

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 remote user. It needs the pub_news 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 table 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.

To extract a database from the consolidated database for remote user field_user:

♦	Click the Remote Users folder, which is in the SQL Remote folder.

♦	Right-click the field_user remote user, and select Extract Database from the popup menu. The Extraction Wizard is displayed.

♦	On page 1, choose to extract from the running database hq.

♦	On the next page, use the dba user ID, with password sql

♦	On the next page, choose to Start Subscriptions for user field_user.

♦	Create the database as file C:\TUTORIAL\FIELD.DB, using a transaction log in the same directory.

♦	Choose to extract all parts of the schema.

♦	Leave the other options at their default settings, and 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 a SQL Anywhere engine and any client applications required. For this tutorial, we leave the database where it is and use ISQL to input and replicate data.

You should connect to the field.db database as DBA and confirm that all the database objects are created.

The system is now ready for replication. For the next step, inserting and replicating data, see the section "Start replicating data".


Tutorial: setting up SQL Remote using ISQL and DBXTRACT
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

Tutorial: setting up SQL Remote using ISQL and DBXTRACT

The following sections are a tutorial describing how to set up a simple SQL Remote replication system for users without Windows 95 or Windows NT 3.51 or later, who cannot run Sybase Central. It may also be useful to users of Sybase Central 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 ISQL. It also describes how to run the DBXTRACT command-line utility to extract remote databases from a consolidated database.

In this tutorial you will act as the DBA of the consolidated database, and set up a simple replication system. The simple example is a primitive model for an office "news" system, with a single table containing messages together with the user who entered them. The table is replicated in a two-level setup with one consolidated database and one remote database. You can install this example on one computer.

The tutorial takes you through the following steps:

♦	Ensure that the consolidated database site and all remote sites have properly configured message systems.

♦	Create a MESSAGE TYPE in the database.

♦	Grant PUBLISH permissions to identify the source of outgoing messages.

♦	Grant REMOTE permissions for each remote database in the setup.

♦	Create publications on the consolidated database.

♦	Create subscriptions for remote users to each required publication.

♦	Ensure that each remote user has an initial copy of the data on their database by synchronizing the data.

♦	Install and run the Message Agent at both consolidated and remote sites.

♦	Start replicating data.

The following sections describe how to carry out each of these steps, apart from the message system installation, which is independent of SQL Anywhere.

 Preparing for the replication tutorial


Preparing for the replication tutorial
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

Tutorial: setting up SQL Remote using ISQL and DBXTRACT

Preparing for the replication tutorial

The following steps prepare you for the replication tutorial:

♦	Create a directory to hold the files you make during this tutorial; for example C:\TUTORIAL.

♦	The tutorial uses two databases: a consolidated database named HQ.DB and a remote database named FIELD.DB. Create these databases using the following statements at a command line:

dbinit c:\tutorial\hq.db

dbinit c:\tutorial\field.db

♦	The database initialization tool for Windows 3.x is DBINITW rather than DBINIT. Under Windows 3.x, you should execute the commands from the Program Manager File>.Run menu or you could make an icon for each command.

♦	If you wish to set up the example system using a file-sharing link you must create a subdirectory for each of the two user IDs in the replication system. Create these subdirectories using the following statements at a command line:

mkdir c:\tutorial\hq

mkdir c:\tutorial\field

♦	If you wish to use a MAPI e-mail system as the message system you need to have two e-mail user IDs and addresses available. In this tutorial these will be user IDs hq_mapi and field_mapi, with MAPI addresses hq_address and field_address.

♦	Connect to HQ.DB from ISQL as user ID DBA, and create a table in the consolidated database to replicate. To do this:

♦	Type CONNECT in the ISQL Command window, and click Execute.

♦	Enter the user ID DBA and the password SQL, and click More.

♦	If the hq database is already running, type hq in the Database Name box. If it is not running, enter the Database File C:\TUTORIAL\HQ.DB. Then click OK to connect.

♦	Enter the following CREATE TABLE statement:

CREATE TABLE news (

   id INT DEFAULT AUTOINCREMENT,

   pub CHAR(30) DEFAULT CURRENT PUBLISHER,

   text CHAR(255),

   PRIMARY KEY ( id, pub )

)

The two-column primary key, containing an autoincrementing integer and a user ID column, is a useful form of primary key for many tables involved in replication; inclusion of the CURRENT PUBLISHER column default prevents users at different databases from inserting rows with the same primary key value, which would cause conflicts. The CURRENT PUBLISHER default identifies each row by the database from which it originates. For more information, see "Designing publications".

You are now ready for the rest of the tutorial.


Set up the consolidated database
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

Set up the consolidated database

This section of the tutorial describes how to set up the consolidated database of a simple replication system.

Setting up a consolidated database involves the following steps:

♦	Create a message type to use for replication.

♦	Grant PUBLISH permissions to a user ID to identify the source of outgoing messages.

♦	Grant REMOTE permissions to all user IDs that are to receive messages.

♦	Create a publication describing the data to be replicated.

♦	Create subscriptions describing who is to receive the publication.

You require DBA authority to carry out these tasks.

 Create a SQL Remote message type

 Grant PUBLISH and REMOTE at the consolidated database

 Create publications and subscriptions


Create a SQL Remote message type
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

Set up the consolidated database

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. Currently, the link must be one of FILE, MAPI, VIM, or SMTP.

♦	An address for this message link, to identify the source of outgoing messages.

You can create a file message type using the following statement:

CREATE REMOTE MESSAGE TYPE file ADDRESS 'hq'

You can create a MAPI message type using the following statement:

CREATE REMOTE MESSAGE TYPE mapi ADDRESS 'hq_address'


Grant PUBLISH and REMOTE at the consolidated database
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

Set up the consolidated database

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 ISQL utility to HQ.DB 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).

The following statements create a publisher:

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 single-user database engine 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 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.

The following statements grant REMOTE permissions to a database with user ID field for a MAPI-based message system:

GRANT CONNECT TO field_user IDENTIFIED BY field_pwd ;

GRANT REMOTE TO field_user TYPE mapi ADDRESS 'field_address' ;

The address string is the MAPI address of field_address, enclosed in single quotes. The MAPI address is not the same as the mail user ID.

The following statements grant REMOTE permissions to a database with user ID field_user for a file-sharing message system:

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. The directory is a subdirectory of the SQLREMOTE environment variable or Directory registry entry, if set, or of the current working directory if SQLREMOTE is not set.


Create publications and subscriptions
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

Set up the consolidated database

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 that replicates all rows of the table news using the following statement:

CREATE PUBLICATION pub_news (   TABLE news)

This publication is about the simplest that can be created. Publications can involve multiple tables, and subsets of the rows and columns in tables. For more information on publications, see "Designing publications".

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.

Create a subscription to the pub_news publication for the remote user field_user:

CREATE SUBSCRIPTION TO pub_news FOR field_user ;

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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

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

 Load the remote database information


Extract the remote database information
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

Set up the remote database

Extract the remote database information

Leave the hq database running, and type the following command at the system command line (all on one line) to extract a database for the user remote from the consolidated database:

dbxtract -c "dbn=hq;uid=dba;pwd=sql" c:\tutorial field_user

In Windows 3.x, you should run the following command either from File>.Run in Program Manager or from an icon:

dbxtracw -c "dbn=hq;uid=dba;pwd=sql" c:\tutorial field_user

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

dbf=c:\tutorial\hq.db

instead of the dbn database name parameter. For details of the DBXTRACT utility and its options, see "The DBXTRACT command-line 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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

Set up the remote database

Load the remote database information

To load the database information, connect to the remote database FIELD.DB from ISQL as user ID DBA and password SQL.

You can do this by typing CONNECT in the ISQL command window, and then entering DBA, SQL, and the database file C:\TUTORIAL\FIELD.DB in the connection dialog box.

Once connected, 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 and confirm that the table is created by typing

SELECT * FROM news.

The system is now ready to start replicating data.


Start replicating data
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

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.

 Send data from the consolidated database

 Receive data at the remote database

 Replicate from the remote database to the consolidated database


Send data from the consolidated database
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

Start replicating data

Send data from the consolidated database

First, connect to the consolidated database hq from the ISQL utility as user ID DBA, with password SQL.

Enter and commit a row into the news database:

INSERT INTO news (text)

VALUES ('Welcome to our news database.') ;

COMMIT ;

To send the new row to the remote database, you must run the Message Agent at the consolidated database. The DBREMOTE program is the Message Agent. The following statement at the command line runs DBREMOTE:

dbremote -c "dbn=hq;uid=dba;pwd=sql"

In Windows 3.x, you should run the following command either from File>.Run in Program Manager or from an icon:

dbremotw -c "dbn=hq;uid=dba;pwd=sql"

These command lines assume that the hq database is currently running on the default server. For information on DBREMOTE command line switches, see "The SQL Remote Message Agent".

If you are running under MAPI, you will be prompted for a MAPI user ID and password in order to connect to the mailing system. You should use the user ID and password for the consolidated database user.


Receive data at the remote database
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

Start replicating data

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. The following statement at the command line runs DBREMOTE on the field database running on a server named field.

dbremote -c "dbn=field;uid=dba;pwd=sql"

If you are running under MAPI, you will be prompted for a MAPI user ID and password in order to connect to the mailing system. You should use the user ID and password for the remote database user.

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.

If you now connect to the remote field database using ISQL, and inspect the news table, you will see that the row entered at the consolidated database has been replicated.


Replicate from the remote database to the consolidated database
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

Start replicating data

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:

♦	INSERT a row at the remote database. For example

INSERT INTO news (text)

VALUES ('Thanks very much.')

♦	COMMIT the row.

♦	With the FIELD.DB database running, run DBREMOTE to send the message to the consolidated database.

dbremote -c "dbn=field;uid=dba;pwd=sql"

(For Windows 3.x, run the DBREMOTW equivalent.)

♦	With the HQ.DB database running, run DBREMOTE to receive the message at the consolidated database:

dbremote -c "dbn=hq;uid=dba;pwd=sql"

♦	Connect to the consolidated database and display news:

 Show the rows of the news table.

1	Type the following statement:

SELECT *FROM news

id	pub	text
1	hq	Welcome to our news database.
2	field	Thanks very much.
The pub column identifies the publisher of the database at which the row was entered. The first row was entered at the consolidated database, and has an entry hq, while the second row was entered at the remote database and so has a value field. With this column as part of the primary key, there will be no conflicts arising from different users at different databases inserting the same primary key value.


A sample publication
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

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 tutorial, in more detail.

To add the publication to the sample database:

♦	Connect to the sample database from ISQL.

♦	Type READ path\salespub.sql, where path is your SQL Anywhere installation 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.


Some sample SQL Remote setups
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

Some sample SQL Remote setups

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

 Server-to-server replication among offices


Server-to-laptop replication for mobile workforces
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

Some sample SQL Remote setups

Server-to-laptop replication for mobile workforces

SQL Remote provides two-way replication between a database on an office network and standalone databases on the laptop computers of sales representatives. Such a setup may use a MAPI e-mail system as a message transport.

The office server may be running a SQL Anywhere network server for Windows NT, Novell NetWare, or OS/2, to manage the company database. The Message Agent at the company database runs as a SQL Anywhere client, either on the same computer as the SQL Anywhere server, or on another computer on the network. For MAPI support, the Message Agent should run on a Windows or Windows NT system.

The laptop computers may be running Windows 95 or Windows for Workgroups, and each sales representative has a SQL Anywhere standalone database engine 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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 26. Introduction to SQL Remote Replication

Some sample SQL Remote setups

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.

Coupled with SQL Anywhere's modest administration requirements, this makes SQL Anywhere ideal for companies with small sales offices and outlets, where the server may be used by only a few people.

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 a MAPI e-mail system to carry the replication, if there is already a company-wide e-mail system. Alternatively, an occasional dialup system and file transfer software can be used to implement a FILE message system.

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.


SQL Remote Administration
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

About this chapter

This chapter details design, set-up, and management issues for SQL Remote administrators.

Some of the ground covered in the chapter "Introduction to SQL Remote Replication" is revisited in more detail, and several new topics are covered.

 SQL Remote administration overview

 SQL Remote message types

 Managing SQL Remote permissions

 Setting up publications

 Designing publications

 Setting up subscriptions

 Synchronizing databases

 How statements are replicated by SQL Remote

 Managing a running SQL Remote setup: overview

 Running the SQL Remote Message Agent

 The SQL Remote message tracking system

 Transaction log and backup management for SQL Remote

 Error reporting and conflict resolution in SQL Remote

 Using passthrough mode for administration


SQL Remote administration overview
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

SQL Remote administration overview

There are two distinct phases of SQL Remote administration:

♦	Designing, implementing, and deploying a SQL Remote replication setup.

♦	Maintaining an operating SQL Remote setup.

SQL Remote is built to provide robust replication within a well-defined setup. Consequently, while many iterations of schema and publication design and testing can be performed, SQL Remote is not designed to support extensive alterations to database object definitions while the replication system is up and running. Upgrading a SQL Remote setup may well involve resynchronizing all remote users.

This chapter describes topics in the following categories:

♦	Design and setup of a SQL Remote installation   This includes creating message types, managing permissions, designing and creating publications, managing subscriptions, as well as extracting databases.

♦	Messages and the Message Agent   Using the Message Agent to send and receive messages, and how the message tracking system works.

♦	Error reporting and conflict resolution   Major inconsistencies, such as two users inserting rows with the same primary key, must be designed out of your publications. Update conflicts, however, can be resolved using triggers.

♦	Direct intervention at remote databases   The passthrough mode enables SQL statements to be applied at remote databases. You may need to make some changes to your database design and applications to make them suitable for replication and updating at multiple sites.

  For more information on such possible changes, see the section "Designing publications".

Sybase Central is the recommended tool for SQL Remote administration. It provides a graphical interface to all the elements of a SQL Remote setup: message types, remote users, publishers, publications, subscriptions, and the database extraction utility for synchronizing databases. If you do not have access to a platform on which Sybase Central can be run (Windows 95 or Windows NT 3.51 or later) you can carry out administration tasks using ISQL to enter SQL statements and using the command-line DBXTRACT utility to synchronize databases. This chapter describes both approaches.


SQL Remote message types
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

SQL Remote message types

You need to define the message types you will use for sending messages before you add remote users to your database.

Supported message types

SQL Remote supports a set of message links. The links currently supported include:

♦	FILE   The FILE link: storage of message files in directories on a shared file system for reading by other databases.

♦	MAPI   Microsoft's messaging API (MAPI) link, used in Microsoft Mail and other electronic mail systems.

♦	VIM   Lotus's Vendor Independent Messaging (VIM), used in Lotus Notes and cc: Mail.

♦	SMTP   Internet Simple Mail Transfer Protocol (SMTP/POP), used in Internet e-mail.

The links are implemented as DLLs on Windows 3.x, Windows 95, Windows NT, and OS/2. The Message Agent for NetWare, DOS and QNX supports the FILE link only, as a compiled library.

 Supported message types

 Specifying a message type

 Message link control parameters


Supported message types
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

SQL Remote message types

Supported message types

This section describes the message types supported by SQL Remote.

The MAPI message system

The Message Application Programming Interface (MAPI) is used in several popular e-mail systems, such as Microsoft Mail. SQL Remote supports the MAPI message system under Windows 3.x, Windows 95, and Windows NT.

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.

Although SQL Remote messages may arrive in the same mail box as e-mail intended for reading, they do not show up in your e-mail inbox. SQL Remote sends 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.

One exception to this is if a message is routed via the Internet, in which case the special message type information is lost. The message then does show up in the recipient's mailbox.

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 link.

The FILE message link is a 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", the user reads the messages from the directory containing their files. Return messages are sent to the address (written to the directory) of the consolidated database.

The FILE link 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 or SQLREMOTE environment variable pointing to the shared directory.

You can also use the FILE link 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.

The VIM message system

The Vendor Independent Messaging system (VIM) is used in Lotus cc: Mail and Lotus Notes.

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.

VIM messages do appear in your mailbox along with mail intended for reading.

The SMTP message system

The Simple Mail Transfer Protocol (SMTP) is used in Internet e-mail products.

To use SQL Remote and a SMTP message system, each database participating in the setup requires a SMTP user ID and address. These are distinct identifiers: the SMTP address is the destination of each message, and the SMTP user ID is the name entered by a user when they connect to their mail box.

SMTP messages do appear in your mailbox along with mail intended for reading.


Specifying a message type
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

SQL Remote message types

Specifying a message type

To specify a message type for a database, you need to specify a message link, and also an address, under that link, for the publisher user ID of the database.

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 link.

The SQL statement to create a message type has the following syntax:

CREATE REMOTE MESSAGE TYPE link-name

ADDRESS address-string

where link-name is one of the message links supported by SQL Remote, and address-string is the publisher's address under that message link.

The SQL statement to alter the publisher's address for a message type has the following syntax:

ALTER REMOTE MESSAGE TYPE link-name

ADDRESS new-address-string

The SQL statement to drop a message type has the following syntax:

DROP REMOTE MESSAGE TYPE link-name

You can create and alter message types in Sybase Central. The Message Type folder is inside the SQL Remote folder.

The address supplied with a message type definition is closely tied to the publisher ID of the database. This is discussed further in the following section.


Message link control parameters
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

SQL Remote message types

Message link control parameters

Each message link has several parameters that govern aspects of its behavior. This section documents these parameters.

Where the parameters are held

The message link control parameters are stored in the registry under Windows NT and Windows 95, and in SQLANY.INI under Windows 3.x.

 FILE message control parameters

 MAPI message control parameters

 SMTP message control parameters

 VIM message control parameters


FILE message control parameters
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

SQL Remote message types

Message link control parameters

FILE message control parameters

The FILE message system uses the following control parameters:

♦	Directory   This is set to the of 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.

The FILE section of the SQLANY.INI file (Windows 3.x) has the following entries:

[FILE]

Directory=path

Debug=yes | no

On NetWare, you should create a file named DBREMOTE.INI in the SYS:\SYSTEM directory to hold the directory setting.


MAPI message control parameters
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

SQL Remote message types

Message link control parameters

MAPI message control parameters

The MAPI message system uses the following control parameters:

♦	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 sends IPC messages, which are not visible in the mailbox. This may be useful if your MAPI provider does not support IPC messages.

♦	IPM_Receive   This can be set to YES or NO (default NO). If set to YES, the MAPI link receives IPM messages, which are visible in the mailbox. If set to NO, the MAPI link receives IPC messages, which are not visible in the mailbox. This may be useful if your MAPI provider does not support IPC messages. Also, it may be useful when receiving messages over the Internet. In this case, the sender might not be using MAPI or the IPC attributes are have been lost.

♦	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.

♦	Debug   When set to YES, displays all MAPI calls and the return codes. This is useful for troubleshooting MAPI support problems. Default is NO.

The MAPI section of the SQLANY.INI file (Windows 3.x) has the following entries:

[MAPI]

IPM_Send=yes | no

IPM_Receive=yes | no

Force_Download=yes | no

Debug=yes | no


SMTP message control parameters
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

SQL Remote message types

Message link control parameters

SMTP message control parameters

The SMTP message system uses the following control parameters:

♦	smtp_host   The name of the computer on which the SMTP Server is running.

♦	smtp_address   The return address if the mail cannot be delivered. If the address of a subscriber database is wrong the mail may be sent but later returned to this address.

♦	local_host   In some environments, the winsock call gethostname cannot return a local host name, yet the local host name is necessary to initiate an SMTP session with an SMTP host. In such environments, you can set local_host, and its value is sent to the SMTP host to identify the local host instead of calling gethostname and gethostbyname.

♦	pop3_host   The name of the computer on which the POP3 host is running. This is generally the same as the SMTP host.

♦	pop3_userid   The user ID for your POP3 account.

♦	pop3_password   The password for your POP3 account.

♦	Debug   When set to YES, displays all SMTP calls and the return codes. This is useful for troubleshooting SMTP support problems. Default is NO.

If all of the fields are set, or if only the Debug field is not set, the login window is not displayed.

The SMTP section of the SQLANY.INI file (Windows 3.x) has the following entries:

[SMTP]

smtp_host=smtp_host

smtp_address=smtp_address

pop3_host=pop3_host

pop3_userid=userid

pop3_password=password

Debug=yes | no


VIM message control parameters
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

SQL Remote message types

Message link control parameters

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 window. It is not applicable to and is ignored under Lotus Notes.

♦	Userid   This corresponds to the User ID field in the cc: Mail login window.

♦	Password   This corresponds to the Password field in the cc: Mail login window. If all of Path, Userid, and Password are set, the login window 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 defaut), the Message Agent looks only for messages of the application-defined type SQLRemoteData. 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.

♦	Send_VIM_Mail   When set to YES, the Message Agent sends messages compatible with SQL 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.

The VIM section of the SQLANY.INI file (Windows 3.x) has the following entries:

[VIM]

Path=path

Userid=userid

Password=password

Debug=yes | no

Receive_All = yes | no

Send_VIM_Mail = yes | no


Managing SQL Remote permissions
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

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 the database. All outgoing SQL Remote messages, including both publication updates and receipt confirmations, are identified by the publisher user ID. The publisher is the user who has been granted PUBLISH permissions on the database, and can be found by selecting the special constant CURRENT PUBLISHER or by opening the SQL Remote folder in Sybase Central. 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. The GRANT REMOTE statement identifies a user ID, as well as a message system and an address appropriate to that message system to where the messages are sent. It also gives the frequency at which messages are sent.

♦	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. The permissions in a three-level SQL Remote setup are summarized in the following diagrams. In each diagram one database is gray; 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 gray database.

Granting the appropriate PUBLISH and CONSOLIDATE permissions at remote databases is done automatically by the database extraction utility.

 Granting and revoking PUBLISH permissions

 Granting and revoking REMOTE and CONSOLIDATE permissions


Granting and revoking PUBLISH permissions
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Managing SQL Remote 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. The GRANT PUBLISH statement identifies a user ID as the publisher user ID of the database.

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 databases is carried out automatically by the database extraction utility.

Granting PUBLISH permissions

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

You can grant PUBLISH permissions from Sybase Central. You should connect to the database as a user with DBA permissions.

♦	Click the SQL Remote folder on the left panel.

♦	Double click Set Publisher, and select a user from the list.

♦	Click OK to set the selected user as the database publisher.

Revoking PUBLISH permissions

The REVOKE PUBLISH statement revokes the PUBLISH permissions from the current publisher:

REVOKE PUBLISH FROM userid

You can revoke PUBLISH permissions from the Sybase Central utility:

♦	Right-click the current publisher.

♦	Click Revoke Publish on the popup menu.

Notes on PUBLISH permissions

♦	Only one user ID on a database can hold PUBLISH permissions at one time. That user ID is called the publisher for the database.

♦	To see the publisher user ID in Sybase Central, open the SQL Remote folder; the publisher is shown on the right panel.

♦	To see the publisher user ID outside Sybase Central, use the CURRENT PUBLISHER special constant. The following statement retrieves the publisher user ID:

SELECT CURRENT PUBLISHER

♦	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.

♦	A column with the DEFAULT CURRENT PUBLISHER setting will be filled in with the user ID of the current publisher. This is useful in ensuring unique primary keys throughout a replication system.

  For more information, see the section "Designing publications".

♦	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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Managing SQL Remote permissions

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. The GRANT REMOTE and GRANT CONSOLIDATE statements identify the message system and address to which replication messages must be sent.

CONSOLIDATE permissions must be granted even at read-only remote databases, for the consolidated database, as receipt confirmations are sent back from the remote databases to the consolidated database. The GRANT CONSOLIDATE statement at remote databases is executed automatically by the database extraction utility.

Granting REMOTE and CONSOLIDATE 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.

In the remote database, the publish and subscribe user IDs are inverted. 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.

The GRANT REMOTE statement identifies a user ID as a remote user, specifies a message type to use for exchanging messages with this user ID, and provides an address to where messages are to be sent. For example, the following statement grants remote permissions to user S_Beaulieu, using a MAPI e-mail system and with MAPI mail address Beaulieu, S:

GRANT REMOTE TO S_Beaulieu

TYPE mapi ADDRESS 'Beaulieu, S'

SEND AT '22:00'

The SEND AT clause is one of three alternatives that specify when messages should be sent to the remote user. The three alternatives are:

SEND EVERY 'HH: MM'   A frequency can be specified in hours and minutes. 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 transaction log has to be processed. You should use as few unique frequencies as possible.

SEND AT 'HH: MM'   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. SQL Remote is not intended for up-to-the-minute replication. Frequencies of less than ten minutes are not recommended.

The following statement grants remote user status to an office in Wakefield, U.K., using a user ID wakefield_office. The statement assumes that both offices are using MAPI e-mail systems as interfaces to internet e-mail, and that the e-mail system has an alias wakefield for the internet e-mail address.

GRANT REMOTE TO wakefield_office

TYPE mapi ADDRESS 'wakefield'

SEND EVERY '02:00'

The following statement grants REMOTE permissions using a file system to user S_Beaulieu.

GRANT REMOTE TO S_Beaulieu

TYPE file ADDRESS 'Beaulieu'

SEND AT '22:00'

The messages are placed in a subdirectory Beaulieu of the current working directory for the Message Agent. If the SQLREMOTE environment variable has been set, or if the Directory setting in the FILE message control parameters (held in the registry of INI files) has been set, the messages are stored under the named directory.

You can add a remote user to a database using Sybase Central:

♦	Click the Users & Groups folder.

♦	Select the user or users you wish to grant REMOTE permissions to, right-click to display a popup menu, and click Set Remote.

♦	For each user, 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.

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.

The following statement grants CONSOLIDATE permissions to the hq_user user ID:

GRANT CONSOLIDATE TO hq_user

TYPE mapi ADDRESS 'hq_address'

There is no SEND clause in this statement. Messages will be sent to the consolidated database every time the Message Agent is run.

Revoking REMOTE and CONSOLIDATE permissions

By analogy with other permissions, 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 remote user permissions also drops any subscriptions for that user.


Setting up publications
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Setting up publications

The publication is the key design element of a SQL Remote data replication. A publication consists of a set of articles. Each article is a selection of rows and columns from a table in the database. Rows can be selected from a table in two ways; a WHERE clause can be included in an article definition, and/or a SUBSCRIBE BY expression can be supplied (usually a column name). In the latter case, rows are sent to subscribers according to a matching value supplied in their subscription.

This section describes the mechanics of setting up publications using Sybase Central. It also describes options open to you in designing publications, governed by the CREATE PUBLICATION statement that is executed by Sybase Central. Careful publication design is crucial to a properly functioning SQL Remote setup.

  For information on designing publications, see "Designing publications".

 Publishing a set of tables

 Publishing a subset of columns

 Publishing a subset of rows using a WHERE clause

 Publishing a subset of rows using a SUBSCRIBE BY expression

 Dropping publications

 Notes on publications


Publishing a set of tables
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Setting up publications

Publishing a set of tables

A simple publication consists of a set of tables, including all columns and rows in each of the tables. The following statement creates such a publication from the sample database:

CREATE PUBLICATION sales (

   TABLE customer,

   TABLE sales_order,

   TABLE sales_order_items,

   TABLE product

)

Not all the tables in the database have been published. For example, subscribers receive the sales_order table, but not the employee table.

Notes

♦	In the sample database, the sales_order and employee tables are related by a foreign key (sales_rep in the sales_order table is a foreign key to the emp_id column in the employee table). Although this could lead to referential integrity problems in the remote database, they are easily avoided by using the database extraction utility: for a discussion of this and other publication design issues, see "Designing publications".

♦	A slightly different publication design (including an article that contains enough of the employee table to satisfy the foreign key relationship) would make the publication more robust; for this section we are publishing whole tables only.

In Sybase Central, you can add a publication to a database from within the SQL Remote folder.

♦	Click the Publications folder, which is inside the SQL Remote folder.

♦	Double-click Add Publication. The Publication Wizard is displayed.

♦	Follow the instructions in the Wizard.

For more information, see the Sybase Central online Help.


Publishing a subset of columns
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Setting up publications

Publishing a subset of columns

The product table keeps information such as unit price and current inventory for a set of products. One column lists the current inventory for each item. In the following single-table publication, this column is not replicated:

CREATE PUBLICATION product (

   TABLE product (   id,

                  name,

                  description,

                  size,

                  color,

                  unit_price

                  )

)

In a multi-table publication, any or all of the tables may have a subset of columns published.

In Sybase Central, the Publication Wizard guides you through selecting a subset of columns in an article.

Notes

♦	All columns in the primary key must be included in the publication.

♦	All columns used in WHERE clauses or SUBSCRIBE BY expressions must be included in the publication.

♦	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.


Publishing a subset of rows using a WHERE clause
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Setting up publications

Publishing a subset of rows using a WHERE clause

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

)

In Sybase Central, the Publication Wizard guides you through creating a WHERE clause for an article.

The WHERE clause in a CREATE PUBLICATION statement may contain a subquery, but subqueries should only be used in very specific circumstances.

  For a description of the circumstances where you can use a subquery in a publication, see "Using subqueries in publications ".


Publishing a subset of rows using a SUBSCRIBE BY expression
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Setting up publications

Publishing a subset of rows using a SUBSCRIBE BY expression

In a typical 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 an expression to be associated with an article. Subscriptions receive rows depending on the value of a supplied expression.

Publications using a SUBSCRIBE BY expression are more compact, easier to understand, and provide better performance than maintaining several WHERE clause publications. The database engine must add information to the transaction log, and scan the transaction log to send messages, in direct proportion to the number of publications. The SUBSCRIBE BY expression allows many different subscriptions to be associated with a single publication, whereas the WHERE clause does not.

The following statement creates a publication of the sales_order table with a SUBSCRIBE BY expression that is just the column sales_rep.

CREATE PUBLICATION pub_orders (

   TABLE sales_order SUBSCRIBE BY sales_rep

)

Each subscription to this publication specifies a value, using the syntax described in "Setting up subscriptions". The subscriber receives updates of those rows for which the SUBSCRIBE BY expression (here a column) matches the value of the subscription parameter (the sales rep's employee id). For example, the following statement creates a subscription for Samuel Singer to the pub_orders publication:

CREATE SUBSCRIPTION

TO pub_orders ( '856' )

FOR SamS

Users can subscribe to more than one publication, and can have more than one subscription to a single publication.

  For more information

♦	For information on how to use subqueries in a publication, see "Using subqueries in publications ".

♦	For more information on creating subscriptions, see "Setting up subscriptions".

♦	In Sybase Central, the Publication Wizard guides you through creating a SUBSCRIBE BY expression for an article.


Dropping publications
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Setting up publications

Dropping publications

Publications can be dropped using the DROP PUBLICATION statement. The following statement drops the publication named pub_orders.

DROP PUBLICATION pub_orders

Dropping a publication has the side effect of dropping all subscriptions to that publication.


Notes on publications
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Setting up publications

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 both a WHERE clause to select a set of rows to be replicated and a SUBSCRIBE BY expression to partition rows by subscription.

♦	DBA authority is required to create publications.

♦	Publications can be altered and dropped by the DBA.

♦	Altering publications in a running SQL Remote setup is likely to cause replication errors, and could lead to loss of data.

♦	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 and triggers".

♦	For other considerations of referential integrity, see the section "Designing publications".


Designing publications
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Designing publications

SQL Remote allows data modification at any site in the system. This is a powerful and useful feature that some replication systems do not have. It does, however, raise the possibility of replication errors. For example, a user at one remote database could delete a row, and a remote user at another site update the same row. When these operations are replicated, if the DELETE arrives at the consolidated database first, the UPDATE will fail.

Proper design of publications can reduce the overhead required by the system and reduce the number of data modification errors and conflicts in the system.

SQL Remote can detect and resolve replication conflicts as long as the data being replicated conforms to certain good practices. Some important kinds of replication error must be avoided altogether with proper replication design. This section describes how to design publications so that important classes of replication errors are avoided.

A full discussion of conflict handling and error reporting is given in "Error reporting and conflict resolution in SQL Remote".

 Replication error and conflict overview

 Designing to avoid primary key errors

 Handling UPDATE conflicts

 Designing to avoid referential integrity errors

 Designing triggers to avoid errors

 Using subqueries in publications

 SUBSCRIBE BY subqueries returning multiple values


Replication error and conflict overview
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Designing publications

Replication error and conflict overview

SQL Remote is designed to allow databases to be updated at many different sites. With a little planning, this can be made to work with few conflicts, but if some basic rules are not followed, replication errors can be a frequent and damaging occurrence. This section describes the kinds of conflict and error that can occur in a replication setup; subsequent sections describe how you can design your publications to avoid errors and manage conflicts.

There is one class of error that can and must be designed out of your SQL Remote publications to ensure that they do not occur. These are primary key errors. Replication errors and conflicts fall into the following categories:

Failures because of an INSERT   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. This is an example of a primary key error, and must be avoided by proper design.

Failures because of a DELETE   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. The second user's operation will not find the row, so the second statement fails.

Updates of primary keys   An update of a primary key has similar effects to a DELETE followed by an INSERT, as far as conflicts are concerned. Any DELETE or UPDATE that refers to the old primary key values will not find the row, and any INSERT that refers to the new primary key will fail. This is an example of a primary key conflict, and must be avoided by proper design.

UPDATE 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 to resolve these conflicts in a way that makes sense for the data being changed. These RESOLVE triggers are described in "RESOLVE UPDATE triggers". Properly handled UPDATE conflicts are not a problem in SQL Remote.

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.

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.

  For information about designing to avoid such conflicts, see "Designing to avoid referential integrity errors".

Not all errors and conflicts can be designed out of a replication system. In particular, UPDATE conflicts will occur in many installations. SQL Remote allows appropriate resolution of UPDATE conflicts as part of the regular operation of a SQL Remote setup, using triggers.

  For information about how SQL Remote handles conflicts as they occur, see "Error reporting and conflict resolution in SQL Remote".

Primary key errors can and must be designed out of publications. This section describes how to design publications so that primary key errors do not occur.


Designing to avoid primary key errors
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Designing publications

Designing to avoid primary key errors

Primary key errors can be avoided if primary keys of tables that may be inserted at more than one site are guaranteed to be unique. This can be achieved by including a column identifying the site at which the INSERT is being made.

For example, a column with a default value of CURRENT PUBLISHER can be used. CURRENT PUBLISHER is the user ID that has been granted PUBLISH permissions on the current database. If such a column is included in the primary key, a row cannot be inserted at more than one site and primary key conflicts can be avoided.

Primary key errors are not corrected in SQL Remote, and designing them out of your publications is essential. Further, SQL Remote applications should not update primary key values.


Handling UPDATE conflicts
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Designing publications

Handling UPDATE conflicts

UPDATE conflicts occur when two users at different databases update the same column, that is not a primary key column, in a row.

Consider a publication that includes the contact table from the sample database. This table includes columns holding information about company contacts, such as the first and last name, the address, and phone and fax numbers.

If one user updates the street column for a particular contact, and another user updates the phone number, there is no conflict, and both updates will be replicated throughout the setup. Should you wish to detect and report such events, you can do so using the VERIFY_ALL_COLUMNS option, described in "RESOLVE UPDATE triggers".

If two users update the street column for a particular contact, then a conflict will occur, as SQL Remote checks that the old values in the database where an update originates made match the values in the database where a replication is being applied.

SQL Remote allows you to define triggers to handle UPDATE conflicts so that data can be altered reliably at more than a single site; these conflict reporting and handling procedures are discussed in "Error reporting and conflict resolution in SQL Remote". When an UPDATE conflict is detected at a consolidated database, the following sequence of events takes place.

♦	Any RESOLVE UPDATE triggers defined for the operation are fired.

♦	The UPDATE takes place.

♦	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.

♦	At remote databases, no RESOLVE UPDATE triggers are fired when a message from a consolidated database contains an UPDATE conflict.

♦	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.


Designing to avoid referential integrity errors
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Designing publications

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 "Setting up publications" 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.

Unreplicated row integrity errors

The pub_orders publication described in "Publishing a subset of rows using a SUBSCRIBE BY expression" includes the rows containing their own sales orders, for each sales rep:

CREATE PUBLICATION pub_orders (

   TABLE sales_order SUBSCRIBE BY sales_rep

)

The following publication also includes all line items from these orders, but will cause problems in replication.

CREATE PUBLICATION pub_orders (

   TABLE sales_order SUBSCRIBE BY sales_rep,

   TABLE sales_order_items

)

The primary key in the sales_order table is id, an order ID number. The sales_order_items table includes the sales order ID as a foreign key to the sales_order table. Although, for example, Samuel Singer receives only his own rows from the sales order table (sales_rep = 856), he receives all the rows of the sales_order_items table.

When another sales rep adds an order, the new sales_order_items entries are replicated to Samuel Singer. The replication fails as Samuel Singer's database does not have a primary key corresponding to the foreign key of the new sales_order_items entries.

One way of of avoiding the problem is to include the sales_rep column in the sales_order_items table. In this case, triggers can be used to fill in the proper values of the user ID in the sales_order_items table. An example is given in the SALESPUB.SQL script included in your installation directory.

Under certain restricted conditions only, you could also use a subquery in a SUBSCRIBE BY expression to solve the problem.

  For information on using subqueries in SUBSCRIBE BY expressions, see the section "Using subqueries in publications ".


Designing triggers to avoid errors
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Designing publications

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 replicates 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 "UPDATE conflict resolution examples". The actions of RESOLVE UPDATE triggers are replicated to remote databases, including the database that caused the conflict.


Using subqueries in publications
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Designing publications

Using subqueries in publications

Subqueries can be used in publications, but require some extra work in order to maintain the integrity of subscriptions.

If no special measures are taken, rows in tables that use subqueries will not be removed from or added to subscriptions properly. This is illustrated by example,and the solution to this problem is then outlined.

Why subqueries are useful

The sample database includes a sales_order table and a sales_order_items table. The sales_order_items table has the order id number as part of its primary key, and also as a foreign key to the sales_order table. The sales_order table contains a region column that is not present in the sales_order_items table.

A publication that replicated the rows in sales_order to subscribers by region may include the following article:

CREATE PUBLICATION SalesPub (

   TABLE sales_order SUBSCRIBE BY region

   ...

)

If this publication was to replicate the rows in the sales_order_items table also, only those items corresponding to orders for the region should be replicated. The following statement shows a subquery that accomplishes this.

CREATE PUBLICATION SalesPub (

   TABLE sales_order SUBSCRIBE BY region

   TABLE sales_order_items SUBSCRIBE BY

      (   SELECT region

         FROM sales_order

         WHERE sales_order.id = sales_order_items.id)

   ...

)

Potential problems with subqueries

There is a potential problem with a subquery SUBSCRIBE BY expression. If the region in a row in the sales_order table is updated, so that the row is removed from a remote user's subscription, that UPDATE is replicated to the remote user as a DELETE, to remove the row from the subscriber's table (see "Replication of updates").

However, the corresponding rows in sales_order_items, which are not affected by the UPDATE, remain in the tables at the remote database. SQL Remote replicates changes as recorded in the transaction log, and nothing in the sales_order_items has changed, so there are no log entries.

Maintaining subscriptions when subqueries are used

SQL Anywhere provides a special syntax of the UPDATE statement in order to allow subqueries to be used.  The syntax is as follows:

UPDATE table

...PUBLICATION publication

...SUBSCRIBE BY expression

...WHERE search-condition

An UPDATE statement of this form must be executed in a BEFORE trigger for any operation that has a side effect of changing a related table's SUBSCRIBE BY values. In this statement, expression is typically a value or a subquery.

The following trigger solves the updated region problem in the example above:

CREATE TRIGGER MoveItems

BEFORE UPDATE OF region

ON sales_order

REFERENCING NEW AS newrow

FOR EACH ROW

BEGIN

   UPDATE sales_order_items PUBLICATION SalesPub

   SUBSCRIBE BY newrow.region

   WHERE sales_order_items.id = newrow.id;

END

The UPDATE statement does not make any alteration to the table itself, but places entries in the transaction log which the Message Agent uses to adjust the rows that are present in remote databases.

Incorrect triggers cause replication errors

If the trigger is not correct, replication errors result. If the incorrect SUBSCRIBE BY value is given, the rows are moved to the wrong remote databases.

An alternative solution is to duplicate the region column in the sales_order_items table, and maintain the value in the column using a trigger. In this way, applications do not have to be aware of the extra column. The sample publication built in the SALESPUB.SQL command file in your SQL Anywhere installation directory uses this approach.


SUBSCRIBE BY subqueries returning multiple values
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Designing publications

SUBSCRIBE BY subqueries returning multiple values

Subqueries in SUBSCRIBE BY clauses can return more than one value.  This is useful because it allows SUBSCRIBE BY publications that are not partitioned into disjoint subsets.

One situation where this feature is useful is where two tables have a many-to-many relationship, and both tables need to have only a subset of rows in the remote databases.

Multiple value SUBSCRIBE BY queries must be used in conjunction with the special UPDATE statement described in the previous section, in order to maintain subscriptions properly.


Setting up subscriptions
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Setting up subscriptions

To subscribe to a publication, each subscriber must be granted REMOTE permissions (see "Granting and revoking REMOTE and CONSOLIDATE permissions") and a subscription must also be created for that user. 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

The following statement creates a subscription for Samuel Singer (user ID SamS, employee ID 856) to the pub_orders publication, defined with a SUBSCRIBE BY expression sales_rep, requesting the rows for Samuel Singer's own sales:

CREATE SUBSCRIPTION

TO pub_orders ( '856' )

FOR SamS

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".


Synchronizing databases
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Synchronizing databases

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.

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.

Synchronizing a remote database can be done in the following ways:

♦	Use the database extraction utility to synchronize the remote database. This is generally the recommended procedure.

♦	Synchronize the remote database manually by loading from files, using the PowerBuilder pipeline, or some other tool.

♦	Synchronize the remote database via the message system using the SYNCHRONIZE SUBSCRIPTION statement.

You should not execute SYNCHRONIZE SUBSCRIPTION at a remote database.

 Using the extraction utility to synchronize databases

 Limits to using the extraction utility

 Synchronizing data over a message system

 Notes on synchronization


Using the extraction utility to synchronize databases
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Synchronizing databases

Using the extraction utility to synchronize databases

The extraction utility can be accessed from Sybase Central, or as the DBXTRACT command-line utility.

The DBXTRACT command-line utility unloads a database schema and data suitable for building a remote database for a named subscriber. It produces a SQL command file with default name RELOAD.SQL and a set of data files. To create the remote database you must:

♦	Create a database using Sybase Central or using the DBINIT utility.

♦	Connect to the database from the ISQL utility, and run the RELOAD.SQL command file. The following statement entered in the ISQL command window 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 (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.

You must complete the following tasks before using the extraction utility at a consolidated database.

♦	You must have created message types for replication.

♦	You must have added a publisher user ID to the database.

♦	You must have added remote users to the database.

♦	You must have added the publication to the database.

♦	You must have created a subscription for the remote users.

For a description of how to carry out these steps, see the tutorial in the chapter "Introduction to SQL Remote Replication".

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

For full information on using the extraction utility from Sybase Central, see the Sybase Central online Help. This section describes one way to extract a database for a remote user from the current consolidated database.

To extract a database for a remote user:

♦	Click the Remote Users folder on the left panel, which is in the SQL Remote folder. The right panel displays the remote users.

♦	Right-click the remote user for whom you wish to extract a database, and select Extract Database from the popup menu. The Extraction Wizard is displayed.

♦	Follow the instructions in the Wizard. The following section describes the options available.

  For more information

For information on the DBXTRACT command-line options, see "The DBXTRACT command-line utility" and the following section.

For information about the extraction utility options, available as command-line options for DBXTRACT or as choices presented by the Database Extraction Wizard, see "Extraction utility options".


Limits to using the extraction utility
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Synchronizing databases

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.

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.

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.

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 reextract 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.


Synchronizing data over a message system
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Synchronizing databases

Synchronizing data over a message system

A subscription is created at a consolidated database using the CREATE SUBSCRIPTION statement:

CREATE SUBSCRIPTION

TO [owner].pubname [ ( string ) ]

FOR userlist

The CREATE SUBSCRIPTION statement defines the data to be received. It does not synchronize or start a subscription.

The SYNCHRONIZE SUBSCRIPTION statement causes the Message Agent (DBREMOTE) to send a copy of all rows in the subscription to the subscriber. It assumes that an appropriate database schema is in place.

The SYNCHRONIZE SUBSCRIPTION statement has the following syntax:

SYNCHRONIZE SUBSCRIPTION

TO [owner].pubname [ ( string ) ]

FOR userlist

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. The syntax of the START SUBSCRIPTION statement is as follows:

START SUBSCRIPTION

TO [owner].pubname [ ( string ) ]

FOR userlist

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, the SYNCHRONIZE SUBSCRIPTION statement 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 the DBUNLOAD utility before synchronizing the database.


Notes on synchronization
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Synchronizing databases

Notes on synchronization

Synchronizing large numbers of subscriptions, or synchronizing subscriptions to large, frequently-used tables, can slow down database access for other users. You may wish to synchronize 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.


How statements are replicated by SQL Remote
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

How statements are replicated by SQL Remote

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.

 Replication of inserts and deletes

 Replication of updates

 Replication of procedures and triggers

 Replication of procedures

 Replication of triggers

 Replication of data definition statements

 Replication of blobs


Replication of inserts and deletes
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

How statements are replicated by SQL Remote

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.


Replication of updates
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

How statements are replicated by SQL Remote

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.

Inclusion of a VERIFY clause for conflict detection

SQL Remote replicates UPDATE statements including a VERIFY clause in the statement.

Consider the following UPDATE statement, entered by an application at a remote database.

UPDATE "dba".product

SET quantity = 23

WHERE id = 300

When this UPDATE is sent to the consolidated database, SQL Remote adds a VERIFY clause to the statement, as follows:

UPDATE "dba".product

SET quantity = 23

VERIFY ( quantity )

VALUES ( 28 )

WHERE id = 300

The VERIFY clause is a check to ensure that the values being updated at the consolidated database are the same as those that were updated at the remote database.

In the example, the UPDATE statement succeeds without a conflict at the consolidated database only if the quantity column has a value of 28 in the row being updated, before the update takes place. If the value is not 28, then any RESOLVE UPDATE trigger created for the table is fired before the UPDATE is applied. The VERIFY clause allows UPDATE conflicts to be detected and resolved by RESOLVE UPDATE triggers.

  For more information on resolution of UPDATE conflicts, see "UPDATE conflict resolution examples".

You can include all columns in the VERIFY clause using the VERIFY_ALL_COLUMNS option, described in "RESOLVE UPDATE triggers".

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.

For example, the pub_orders publication is defined as follows:

CREATE PUBLICATION pub_orders (

   TABLE sales_order SUBSCRIBE BY sales_rep

)

Samuel Singer, with user ID SamS, has a subscription to the pub_orders publication as follows:

CREATE SUBSCRIPTION

TO pub_orders ( '856' )

FOR SamS

Pamela Savarino, with user ID PamS, has a subscription to the pub_orders publication as follows:

CREATE SUBSCRIPTION

TO pub_orders ( '949' )

FOR PamS

An UPDATE to the sales_order table that changes the sales_rep value of a row from 856 to 949 is replicated to Samuel Singer as a DELETE statement, and to Pamela Savarino as an INSERT statement.


Replication of procedures and triggers
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

How statements are replicated by SQL Remote

Replication of procedures and triggers

Any replication system is faced with two broad choices when replicating a procedure call. Either the call itself can be replicated (so that a procedure with the same name and parameters is called at the replicate site), or the procedure can be replicated by replicating the individual actions (INSERTs, UPDATEs, DELETEs) of the procedure.

When operations are applied by the Message Agent, the same triggers fired at the publishing database are fired at the subscriber database. If the actions taken by a trigger at the publishing database were included in replication messages, these actions would occur twice.

The current release of SQL Remote does not allow procedures to be included in publication definitions, and so implements the second of the two choices; to replicate the actions of the procedure, not the call. This is described in the following section.


Replication of procedures
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

How statements are replicated by SQL Remote

Replication of procedures

SQL Remote replicates procedures by replicating the actions of a procedure. The call itself is not reproduced. Consequently, procedures that modify non-replicated data do not cause problems. If the call to a procedure were replicated, a version of the procedure would have to be written that does not carry out those actions that modify unreplicated data, for the replicate database.


Replication of triggers
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

How statements are replicated by SQL Remote

Replication of triggers

SQL Remote does not replicate actions performed by triggers. SQL Remote replicates triggers by assuming the trigger is defined remotely. This avoids permissions issues and the possibility of each action occurring twice. There are some exceptions to this rule, described below.

RESOLVE UPDATE trigger actions

The actions carried out by 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. 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 will double count, because the BEFORE UPDATE trigger will fire when the UPDATE is replicated. 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 Message Agent has a command-line switch that causes it to replicate all trigger actions.  This is the DBREMOTE -t switch.

If you do use this switch, 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.


Replication of data definition statements
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

How statements are replicated by SQL Remote

Replication of data definition statements

Only data manipulation statements are replicated to other databases. 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, see "Using passthrough mode for administration".


Replication of blobs
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

How statements are replicated by SQL Remote

Replication of blobs

SQL Remote includes special methods for replication of LONG VARCHAR, LONG BINARY, TEXT, and IMAGE data types: values that are longer than 256 characters.

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.

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 200Kb in length, this causes 4Mb 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 (200Kb of messages).


Managing a running SQL Remote setup: overview
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Managing a running SQL Remote setup: overview

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.

Making changes to a database schema at one database within the system will 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 stop changes being made to the database, make some changes to the database schema, and restart.

Many changes to a database schema will produce conflicts 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.

The following are examples of changes that should not be made to a deployed and running SQL Remote setup:

♦	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 including 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.

♦	DROP SUBSCRIPTION.

♦	Unload and reload a database. If a 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.


Running the SQL Remote Message Agent
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Running the SQL Remote Message Agent

The SQL Remote Message Agent (DBREMOTE.EXE, or DBREMOTW.EXE under Window 3.x) is a key component in SQL Remote replication. It carries out the following functions:

♦	It scans the transaction log 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 processes incoming messages, and applies them in the proper order to the database.

♦	It maintains the message tracking information in the system tables, and manages the guaranteed transmission mechanism.

The Message Agent can be run in either batch or continuous mode. The options available depend on the sending frequency specified in the GRANT REMOTE statements for remote users.

♦	If any remote user does not have SEND AT or SEND EVERY set in the GRANT REMOTE statement, the Message Agent can run only in batch mode. In this mode, it processes incoming messages, scans the transaction log once, and stops. In all supported operating systems other than Windows or Windows NT, the Message Agent closes. In Windows or Windows NT, you can run the Message Agent with the -k command-line switch to close the window automatically after scanning the transaction log.

♦	If all remote users have SEND AT or SEND EVERY set, the Message Agent runs continuously by default. It can be run in batch mode by specifying the -b command-line switch. After the Message Agent processes incoming messages, it determines which remote users should now be sent messages. If any users are due for messages, they are sent. When no users are due for messages, the Message Agent waits. While the Message Agent is waiting, it checks frequently for incoming messages, and applies them when they arrive.

Running the Message Agent continuously can be useful particularly at a consolidated database, where messages may be coming in frequently and many outgoing messages may need to be sent. If you are running SQL Remote on Windows NT, you can run the Message Agent as an NT service.

  For information on using NT services, see the chapter "Running Programs as Services".

Running the Message Agent in batch mode is most likely useful at a remote database. For example, an application could run the Message Agent once per day at a remote site. You can choose to process only incoming or outgoing messages using the -r and -s command-line switches, respectively.

  For a full description of DBREMOTE command-line switches, see "The SQL Remote Message Agent".

 The Message Agent and replication security

 Running the Message Agent when recovery is difficult


The Message Agent and replication security
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Running the SQL Remote Message Agent

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:

♦	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.

♦	When connecting from the Message Agent, a user ID with REMOTE DBA authority has full DBA permissions on the database.

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).

You can grant REMOTE DBA permissions to a user ID named dbremote as follows:

GRANT REMOTE DBA

TO dbremote

IDENTIFIED BY dbremote

In SQL Anywhere, you can add the REMOTE DBA authority to a remote user by checking the appropriate option in the New Remote User Wizard.


Running the Message Agent when recovery is difficult
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Running the SQL Remote Message Agent

Running the Message Agent when recovery is difficult

In this section, an option for running the Message Agent in situations where database recovery is complicated, or backups are insecure, is described. The -u DBREMOTE command-line option causes the Message Agent to process only those transactions before the latest backup.

As the Message Agent relies on entries in the transaction log, transaction log management is an important part of SQL Remote administration. For a discussion of transaction log management, see "Transaction log and backup management for SQL Remote".

When the -u option is used, outgoing transactions and confirmation of incoming transactions are not sent until they are no longer in the live transaction log. This feature is useful in several situations:

♦	No transaction log mirror on the consolidated database   It is strongly recommended that a transaction log mirror be used on a SQL Remote consolidated database. In the absence of a mirror, media failure on the transaction log might result in loss of transactions.

If the -u option is used, recovery in such a situation will not require remote users' databases to be re-extracted, as no transactions have been replicated to remote users until the transactions have been backed up.

♦	Offsite backup is required for protection against a total site failure   In this case the transaction log may be backed up across a WAN to another site.

If the -u option is used, and there is a total site failure, recovery will not require remote users to be re-extracted because no transactions have been replicated to remote users until the transactions have been backed up to another site.

♦	Participation in Replication Server replication   In this case, the recovery plan is complicated because it needs to recover to a point where all databases are consistent.

If there is a possibility of an enterprise SQL Server losing committed transactions on recovery (for example,. not using SQL Server transaction log mirroring), then the SQL Anywhere database needs to be restored to a point consistent with the enterprise (throwing away the current transaction log). In this case, it is desirable to prevent remote databases from receiving transactions until they have been backed in a way that they will not be lost.


The SQL Remote message tracking system
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

The SQL Remote 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 SYSREMOTEUSER 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 SYSREMOTEUSER is maintained properly at each end of the subscription.

 Status information in the SYSREMOTEUSER system table

 Tracking messages by transaction log offsets

 Handling of lost or corrupt messages


Status information in the SYSREMOTEUSER system table
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

The SQL Remote message tracking system

Status information in the SYSREMOTEUSER system table

The SYSREMOTEUSER system table contains a row for each subscriber, with status information for messages sent to and received by that subscriber. SYSREMOTEUSER at the consolidated database contains a row for each remote user. SYSREMOTEUSER at each remote database contains a single row maintaining information for the consolidated database. (Recall that the consolidated database subscribes to publications from the remote database.)

The SYSREMOTEUSER table at each end of a subscription is maintained by the Message Agent.


Tracking messages by transaction log offsets
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

The SQL Remote message tracking system

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.

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 DBREMOTE -l switch to change this setting.

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.

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.

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 SYSREMOTEUSER 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.

The SYSREMOTEUSER 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.

The log_send column is updated by the Message Agent based on the SEND frequency information (SEND AT or SEND EVERY as specified in the GRANT REMOTE statement).  The value of log_send must be greater than that of log_sent for a user in order for messages to be sent to that user.


Handling of lost or corrupt messages
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

The SQL Remote message tracking system

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.

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.


Transaction log and backup management for SQL Remote
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Transaction log and backup management for SQL Remote

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 resynchronize 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 the chapter "Backup and Data Recovery".

Access to old transactions

In many setups, users of laptop 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.

You can specify a directory on the DBREMOTE command line. This directory is where old transaction logs are kept. This section describes how you can set up a backup procedure to ensure that such a directory is kept in proper shape.

Backup options to use

One of the options to the backup utility is to rename the transaction log on backup and restart. For the DBBACKUP command-line utility, this is the -r command-line switch. It is recommended that you use this option when backing up the consolidated database and remote database transaction logs.

To see how this option works, consider a consolidated database named HQ.DB, in directory C:\HQ, with a transaction log in directory D:\HQLOG\HQ.LOG. Backing up this transaction log to a directory E:\HQBAK using the rename and restart option carries out the following tasks:

♦	Backs up the transaction log, creating a backup file E:\HQBACK\HQ.LOG.

♦	Renames the existing transaction log to D:\HQLOG\HQ.LNN, where nn is the lowest available integer, starting at 00.

♦	Starts a new transaction log, as D:\HQLOG\HQ.LOG.

After several backups, the directory D:\HQLOG will contain a set of sequential transaction logs.

You can run the Message Agent with access to these log files using the following command line:

dbremote -c "dbn=hq;..." d:\hqlog

The log directory should not contain any transaction logs other than the sequence of logs generated by this backup procedure.

You can also run the Message Agent pointing to the directory where backup copies are held. However, the backup utility makes backups to the same file name each time by default, so you will need to ensure that old logs are renamed before subsequent backups.

 Using the DELETE_OLD_LOGS option

 Backup procedures at remote databases

 Upgrading consolidated databases

 The Unload utility and replication


Using the DELETE_OLD_LOGS option
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Transaction log and backup management for SQL Remote

Using the DELETE_OLD_LOGS option

The DELETE_OLD_LOGS database option is set by default to OFF. If it is set to ON, then the old transaction logs will be 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. This option can help to manage disk space in replication setups.

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.


Backup procedures at remote databases
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Transaction log and backup management for SQL Remote

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 command-line switch to eliminate the need to rename the transaction log on the remote computer when the database engine is shut down. The -x option renames transaction log after it has been scanned for outgoing messages.


Upgrading consolidated databases
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Transaction log and backup management for SQL Remote

Upgrading consolidated databases

This section describes issues in upgrading a consolidated database in a SQL Remote environment. The same considerations apply to SQL 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".


The Unload utility and replication
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Transaction log and backup management for SQL Remote

The Unload utility and replication

If a database is participating in replication, it cannot be unloaded and reloaded without re-synchronizing the databases in the replication system.

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.


Error reporting and conflict resolution in SQL Remote
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Error reporting and conflict resolution in SQL Remote

A replication error occurs when a replication cannot be carried out because of some change to the database. If an INSERT statement is received at a database, but a row with the same primary key values has already been inserted, then the INSERT will fail. When a SQL operation fails, it generates an error message from the database. The other operations in the message are still applied.

Primary key errors must be avoided in SQL Remote setups. These errors can be avoided by proper design of publications. Update conflicts can be resolved by SQL Remote using a RESOLVE UPDATE trigger. Properly handled update conflicts are not a problem: they are an integral part of the replication system.

 Error reporting and conflict resolution

 Error reporting in the Message Agent output

 RESOLVE UPDATE triggers

 UPDATE conflict resolution examples


Error reporting and conflict resolution
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Error reporting and conflict resolution in SQL Remote

Error reporting and conflict resolution

Errors are reported and conflicts resolved by SQL Remote as follows:

SQL statement failures   INSERT errors (two users at different databases insert an identical primary key) and other failures of operations contained in replication messages, are reported in the DBREMOTE output.

UPDATE conflicts   SQL Anywhere provides a special form of trigger, the RESOLVE UPDATE trigger, which is triggered by UPDATE conflicts at a consolidated database. In this way, you can design appropriate resolutions based on the situation. If an UPDATE conflict occurs at the consolidated database, any RESOLVE UPDATE triggers are fired, then the UPDATE is applied. Both the RESOLVE UPDATE trigger actions and the UPDATE itself are replicated to other databases. If an update conflict is detected at a remote database, no RESOLVE UPDATE triggers are fired, and the UPDATE is carried out. Examples are provided in the following section.


Error reporting in the Message Agent output
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Error reporting and conflict resolution in SQL Remote

Error reporting in the Message Agent 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 log includes the following:

♦	Listing of messages applied.

♦	Listing of failed SQL statements.

♦	Listing of other errors.

In addition, UPDATE conflicts can be inserted into a table by a RESOLVE UPDATE trigger, and reports from that table can be used to track such conflicts.

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 will cause the known error.  The trigger should signal the REMOTE_STATEMENT_FAILED SQLSTATE or SQLCODE value.  For example, if you wish to not report failed INSERT statements on a table 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.

Using the REPLICATION_ERROR option

With the REPLICATION_ERROR database 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.

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 eror.

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.

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 "SET OPTION statement".


RESOLVE UPDATE triggers
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Error reporting and conflict resolution in SQL Remote

RESOLVE UPDATE triggers

An UPDATE conflict is detected by the database engine as a failure of the VERIFY clause values to match the rows in the database.

When an UPDATE conflict is detected, the database engine takes two actions:

♦	Any RESOLVE UPDATE triggers are fired.

♦	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.

This section describes RESOLVE UPDATE triggers. These 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, ...

[ FROM table-list ]

[ VERIFY (column-name, ...)

   VALUES ( expression, ...) ]

[ WHERE search-condition ]

The VERIFY clause 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.

The verify clause is useful only for single-row updates. However, even 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.

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 "row 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. 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.


UPDATE conflict resolution examples
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Error reporting and conflict resolution in SQL Remote

UPDATE conflict resolution examples

This section describes some ways of using RESOLVE UPDATE triggers to handle UPDATE conflicts.

Example: inventory control

The products table of the sample database has 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 rep at a remote database enters an order, depleting the stock of small tank top tee shirts (product ID 300) 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 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-SQL Anywhere detects that the update is from 28 to 23, but that the current value of the column is 68.

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:

♦	The original remote UPDATE changed the value from 28 to 23.

♦	The warehouse's entry is replicated to the remote database, but fails as the old value is not what was expected.

♦	The changes made by the RESOLVE UPDATE trigger are replicated to the remote database.

Example: resolving date conflicts

Suppose the contact table in the sample database had a date column holding the most recent contact with each individual. Update conflicts on this column should be resolved in favor of the most recent date.

One representative talks with the contact on a Friday, but does not upload his changes to the consolidated database until the next Monday. Meanwhile, a second representative meets the contact on the Saturday, and updates her 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.

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.


Using passthrough mode for administration
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Using passthrough mode for administration

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.

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;

The following statement starts a passthrough session which 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.

Notes on using passthrough mode

♦	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,l0o

 Stored procedures and control statements in passthrough mode


Uses and limitations of passthrough mode,l0o
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Using passthrough mode for administration

Uses and limitations of passthrough mode,l0o

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. 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 one 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.


Stored procedures and control statements in passthrough mode
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 27. SQL Remote Administration

Using passthrough mode for administration

Stored procedures and control statements 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.


Running Programs as Services
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 28. Running Programs as Services

About this chapter

The material in this chapter applies only to users of SQL Anywhere on Windows NT.

The SQL Anywhere database server and engine, as well as the SQL Anywhere Client, the Open Server Gateway, the SQL Remote Message Agent, and the SQL Anywhere Replication Agent (available as a separate product) can be run as services under Windows NT. This chapter describes services, their benefits, and how to run SQL Anywhere executables as services.

The chapter also describes how to use Sybase Central to manage SQL Anywhere services.

 Introduction to services

 Managing services

 Adding and removing SQL Anywhere services

 Configuring SQL Anywhere services

 Starting and stopping services

 Running more than one service

 Monitoring a SQL Anywhere network server service

 The Windows NT Control Panel Service Manager


Introduction to services
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 28. Running Programs as Services

Introduction to services

Although SQL Anywhere applications such as the network server and database engine can be run like any other Windows NT executable, there are limitations to running them in this manner, particularly for the SQL Anywhere network server.

When you run a program, it runs under your NT login session: if you then log off the computer, the program terminates. As only one person can be logged on to Windows NT 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 in to the computer running SQL Anywhere in order for the program to keep running. In addition to the inconvenience, this arrangement can present a security risk, as the NT computer must be left in a logged on state.

Installing an application as an service enables it to run even when you log off. For a full description of services and how to use them, see your Windows NT documentation. Several SQL Anywhere executables can be run as Services.

Programs that can be run as a service

The following SQL Anywhere programs can be run as a service:

♦	The network server (DBSRV50.EXE).

♦	The standalone engine (DBENG50.EXE).

♦	The SQL Anywhere Client (DBCLIENT.EXE).

♦	The Open Server Gateway (DBOS50.EXE).

♦	The SQL Anywhere  Replication Agent (DBLTM.EXE : available separately).

♦	The SQL Remote Message Agent (DBREMOTE.EXE).

♦	A sample application.

Not all these applications are supplied in all editions of SQL Anywhere.

The LocalSystem account

When you start a service, it logs on using a special system account called LocalSystem (or using another account you specify). The service is not tied to the user ID of the person starting it, and is not stopped when that person logs off. A service can also be configured to start automatically whenever the NT computer is started, before any user even logs on.

Although you can control most aspects of services from the Services option in the Windows NT Control Panel, Sybase Central provides a more convenient and comprehensive way of managing SQL Anywhere services.


Managing services
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 28. Running Programs as Services

Managing services

You can carry out the following service management tasks from Sybase Central:

♦	Add, edit, and remove SQL Anywhere services.

♦	Start, stop, and pause SQL Anywhere services.

♦	Modify the parameters governing a SQL Anywhere service.

♦	Add databases to a SQL Anywhere engine or server service, so that you can run several databases at one time.

The service icons in Sybase Central display the current state of each SQL Anywhere service using a traffic light icon (running, paused, or stopped).

 Service polling frequency


Service polling frequency
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 28. Running Programs as Services

Managing services

Service polling frequency

Sybase Central polls at specified intervals to check the state (started, stopped, paused, removed) of each service, and updates the icons to display the current state.

 To alter the Sybase Central polling frequency:

1	In Sybase Central, open the Services folder.

2	Right-click the icon of any service in the right panel of Sybase Central, and select Polling from the popup menu.

3	Set the polling frequency. The frequency applies to all services, not just the one selected.

The value you set in this window is saved for subsequent sessions, until you change it.


Adding and removing SQL Anywhere services
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 28. Running Programs as Services

Adding and removing SQL Anywhere services

This section describes how to add and remove SQL Anywhere services.

 Adding a SQL Anywhere service

 Removing a SQL Anywhere service


Adding a SQL Anywhere service
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 28. Running Programs as Services

Adding and removing SQL Anywhere services

Adding a SQL Anywhere service

You may wish to set up services for one or more of the SQL Anywhere programs that can be run as a service. This section describes how to set up services using Sybase Central.

 To add a new SQL Anywhere service:

1	In Sybase Central, open the Services folder.

2	Double-click Add Service. The Service Creation Wizard is displayed..

3	Follow the instructions in the wizard to define the service you are creating:

♦	Select the type service you wish to create.

♦	Enter a name for the service. Service Names must be unique within the first eight characters.

♦	Choose whether you wish the service to start automatically (that is, whenever the computer starts NT), manually (you need to start the service from Sybase Central each time), or if you want the service disabled. You may want to select Disabled if you are setting up a service for future use.

♦	Specify the name and complete path of the executable you wish to run as a service.

♦	Enter a set of command-line switches for the executable to use in the Parameters box. For example, if you wish a network server to run using the sample database with a cache size of 20Mb, and a name of myserver, you would enter the following in the Parameters box:

-c 20M

-n myserver c:\sqlany50.sademo.db

Line breaks are optional. For information on valid command-line switches, see the description of each program in the chapter "SQL Anywhere Components".

♦	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 NT desktop, check Allow Service to Interact with Desktop. If this option is unchecked, no icon or window appears on the desktop.

  For more information on the configuration options, see "Configuring SQL Anywhere services".


Removing a SQL Anywhere service
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 28. Running Programs as Services

Adding and removing SQL Anywhere services

Removing a SQL Anywhere service

Removing a SQL Anywhere service removes the server name from the list of services. Removing a SQL Anywhere service does not remove any SQL Anywhere software from your hard disk.

If you wish to re-install a SQL Anywhere service that you have removed, you will need to reenter the command-line switches.

 To remove a SQL Anywhere service:

1	In Sybase Central, open the Services folder.

2	Right-click the icon of the service you wish to start, and select Delete from the popup menu


Configuring SQL Anywhere services
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 28. Running Programs as Services

Configuring SQL Anywhere services

A SQL Anywhere service runs a SQL Anywhere database server or other application with a set of command-line switches. For a full description of the command-line switches for each of the SQL Anywhere applications, see the chapter "SQL Anywhere Components" and the SQL Anywhere Network Guide.

In addition to the command-line switches, SQL Anywhere services accept other parameters that specify the account under which the service will run and the conditions under which it will start.

 To change the parameters for a SQL Anywhere service:

1	In Sybase Central, open the Services folder.

2	Right-click the icon of the service whose parameters you wish to change in the right panel of Sybase Central, and select Properties from the popup menu.

3	Alter the parameters as needed in the tabs of the Property sheet.

4	When you have altered the parameters as you wish, click OK to accept and save the changes.

Changes to a service configuration do not take effect immediately. They take effect next time the service is started. The Startup option is applied next time Windows NT is started.

 Setting the startup option

 Entering command-line switches

 Setting the account options

 Changing the executable file

 Adding new databases to a server or engine service


Setting the startup option
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 28. Running Programs as Services

Configuring SQL Anywhere services

Setting the startup option

The following options govern startup behavior for a SQL Anywhere service:

♦	Automatic   If you choose the Automatic setting, the SQL Anywhere service starts whenever the NT operating system is started on the computer. This setting is appropriate for database servers and other applications that are run all the time.

♦	Manual   If you choose the Manual setting, the SQL Anywhere service starts only when a user with Administrator permissions starts it. For information about Administrator permissions, see your Windows NT documentation.

♦	Disable   If you choose the Disable setting, the SQL Anywhere service will not start.


Entering command-line switches
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 28. Running Programs as Services

Configuring SQL Anywhere services

Entering command-line switches

The Configuration tab of the service property sheet provides a text box for entering command-line switches for a service. You should enter command-line switches that govern the behavior of the service in this box. You should not enter the name of the program executable in this box.

Examples

♦	To start a network server service running two databases, with a cache size of 20 Mb, and with a name of my_server, enter the following in the Parameters box:

-c 20M

-n my_server

c:\sqlany50\db_1.db

c:\sqlany50\db_2.db

♦	To start a SQL Remote Message Agent service, connecting to the sample database as user ID DBA, enter the following:

-c "uid=dba;pwd=sql;dbn=sademo"

♦	To start a SQL Anywhere Client, connecting to a server named my_server, enter the following:

my_server

The figure illustrates a sample Property sheet.

  The command-line switches for a service are the same as those for the executable. For a full description of the command-line switches for each program, see the chapter "SQL Anywhere Components".


Setting the account options
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 28. Running Programs as Services

Configuring SQL Anywhere services

Setting the account options

You can choose under which account the SQL Anywhere service will run. Most services run under the special LocalSystem account, and this is the default option for SQL Anywhere services. You can set the service to log on under another account by clicking Account and entering the account information.

If you choose to run the SQL Anywhere service under an account other than LocalSystem, that account must have the "log on as a service" privilege. This can be granted from the NT User Manager application, under Advanced Privileges.

When an icon appears on the taskbar

Whether or not an icon for the service appears on the taskbar or desktop depends on the account that is selected, and whether Allow Service to Interact with Desktop is checked, as follows:

♦	If a service is running under LocalSystem, and Allow Service to Interact with Desktop is checked in the Service Configuration window, an icon appears on the desktop of every user logged in to NT on the computer running the service. Consequently any user can open the application window and stop the program that is running as a service.

♦	If a service is running under LocalSystem, and Allow Service to Interact with Desktop is unchecked in the Service Configuration window, 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 is running 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
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 28. Running Programs as Services

Configuring SQL Anywhere services

Changing the executable file

To change the program executable file associated with a service, click the Configuration tab on the service property sheet and enter the new path and file name in the Path of Executable box.

If you move an executable file to a new directory, you must modify this entry.


Adding new databases to a server or engine service
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 28. Running Programs as Services

Configuring SQL Anywhere services

Adding new databases to a server or engine service

Each SQL Anywhere network server or standalone engine can run more than one database. If you wish to run more than one SQL Anywhere database at a time, we recommend that you do so by attaching new databases to your existing SQL Anywhere service, rather than by creating new services.

 To add a new database to a SQL Anywhere service:

1	Ensure that your SQL Anywhere server is selected in the list of database servers.

2	Double click to change the parameters for the service.

3	Add the filename of the new database to the end of the list of parameters.

4	Click OK to save the changes.

The new database will not be added to the service immediately. It is loaded next time the service is started.

Databases can be started on running servers by client applications, such as ISQL..

  For a description of how to start a database on a server from ISQL, see "START DATABASE statement". For a description of how to implement this function in an Embedded SQL application, see the db_start_database function in the chapter "The Embedded SQL Interface". 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.


Starting and stopping services
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 28. Running Programs as Services

Starting and stopping services

This section describes how you can start, stop, and pause services from Sybase Central.

 Starting a SQL Anywhere service

 Stopping a SQL Anywhere service

 Pausing a SQL Anywhere service


Starting a SQL Anywhere service
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 28. Running Programs as Services

Starting and stopping services

Starting a SQL Anywhere service

 To start a SQL Anywhere service:

1	In Sybase Central, open the Services folder.

2	Right-click the icon of the service you wish to start, and select Start from the popup menu

If you close Sybase Central, the SQL Anywhere service will not be stopped. If you log off the computer, the SQL Anywhere service keeps running.


Stopping a SQL Anywhere service
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 28. Running Programs as Services

Starting and stopping services

Stopping a SQL Anywhere service

Stopping a SQL Anywhere service for an engine or server closes all connections to the database and unloads the database server. For other applications, the program is closed down.

 To stop a SQL Anywhere service:

1	In Sybase Central, open the Services folder.

2	Right-click the icon of the service you wish to start, and select Stop from the popup menu


Pausing a SQL Anywhere service
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 28. Running Programs as Services

Starting and stopping services

Pausing a SQL Anywhere service

Pausing a service prevents any further action being taken by the application, but does not shut the application down or, in the case of server services, close any client connections to the database. Most users will not need to pause their SQL Anywhere services.

 To pause a SQL Anywhere service:

1	In Sybase Central, open the Services folder.

2	Right-click the icon of the service you wish to start, and select Pause from the popup menu


Running more than one service
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 28. Running Programs as Services

Running more than one service

This section describes some topic specific to running more than one service at a time.

 Service dependencies

 Service groups overview

 Managing service dependencies

 Possible problems running more than one server as a service


Service dependencies
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 28. Running Programs as Services

Running more than one service

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 SQL Anywhere Client and also a SQL Remote Message Agent or SQL Anywhere Log Transfer Manager to assist in replication.

In cases such as these, it is important that the services start in the proper order. If a SQL Remote Message Agent service starts up before the SQL Anywhere Client has started, it will fail because it cannot find the server.

You can prevent these problems using service groups. You can manage the service groups from Sybase Central.


Service groups overview
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 28. Running Programs as Services

Running more than one service

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	SQLANYServer
Standalone engine	SQLANYEngine
Client	SQLANYClient
SQL Remote Message Agent	SQLANYRemote
Replication Agent	SQLANYLTM
Open Server Gateway	SQLANYOSG
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.

 To check which group a service belongs to:

1	In Sybase Central, open the Services folder.

2	Right-click the icon of the service you wish to start, and select Properties from the popup menu.

3	Click the Dependencies tab. The top text box displays the name of the group to which the service belongs.

 To change which group a service belongs to:

1	In Sybase Central, open the Services folder.

2	Right-click the icon of the service you wish to start, and select Properties from the popup menu.

3	Click the Dependencies tab. Click Look Up to display a list of available groups on your system.

4	Select one of the groups, or type a name of a new group, and click OK to assign the service to that group.


Managing service dependencies
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 28. Running Programs as Services

Running more than one service

Managing service dependencies

With Sybase Central you can ensure that at least one member of a each of a list of service groups, and each of a list of services, has started before the current service. The members of these lists are called dependencies.

For example, you may wish to ensure that a particular network server has started before a SQL Remote Message Agent that is to run against that server starts.

 To add a service or group to a list of dependencies:

1	In Sybase Central, open the Services folder.

2	Right-click the icon of the service you wish to start, and select Properties from the popup menu.

3	Click the Dependencies tab. Click Add Service or Add Group to add a service or group to the list of dependencies..

4	Select one of the services or groups from the list, and click OK to add the service or group to the list of dependencies.


Possible problems running more than one server as a service
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 28. Running Programs as Services

Running more than one service

Possible problems running more than one server as a service

You may experience problems if you run more than one SQL Anywhere network server as a service at a time. Under some circumstances, it cannot be guaranteed that the correct service will respond to a client that sends a request to the database server as a broadcast. Broadcasts are typically used if you are using the TCP/IP protocol, or the IPX protocol on a Novell network without using the bindery. The broadcast is only used to find the server during startup.

We recommend that you not run more than one SQL Anywhere network server service at a time.


Monitoring a SQL Anywhere network server service
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 28. Running Programs as Services

Monitoring a SQL Anywhere network server service

Sybase Central shows whether a service is running, stopped, paused, or not installed. You can find out more information about the state of the server, and control connections to the server, from the following utilities

♦	The database server display   When you start a SQL Anywhere network server service, the database server icon appears at the bottom of your screen. Double clicking this icon displays the server display. This display allows you to monitor the database server, as well as close connections from the server.

♦	The DBWATCH remote monitoring utility   The DBWATCH display is the same as the database server display. For a description of DBWATCH, see the SQL Anywhere Network Guide.

The database server icon is generally displayed on the screen of the machine on which it is running, and server monitoring is generally done from the database server display. There are some cases when services are not allowed to open Windows, and you need an alternative means to monitor the service. These cases are:

♦	When there is no current logon to Windows NT.

♦	When the service is running under a normal user account (not LocalSystem), and that account is not logged on.

Also, you may wish to monitor the server from a remote machine. In all these cases, you can use Sybase Central or DBWATCH to monitor and control the server.


The Windows NT Control Panel Service Manager
User's Guide

PART 3. Using SQL Anywhere

CHAPTER 28. Running Programs as Services

The Windows NT Control Panel Service Manager

You can carry out all the service management of SQL Anywhere database servers from Sybase Central. You do not need to use the Windows NT Service Manager in the Control Panel.

If you open the NT Service Manager, a list of services is given. The names of the SQL Anywhere services are formed from the Service Name you provided when installing the service, prefixed by SQL Anywhere. All the SQL Anywhere services you have installed will be found together in the list.

You cannot install or configure parameters for the SQL Anywhere services using the NT Service Manager: you must use Sybase Central.


Transact-SQL Compatibility
User's Guide

PART 4. Transact-SQL Compatibility

Transact-SQL is the SQL dialect supported by Sybase SQL Server. SQL Anywhere supports a large percentage of Transact-SQL, and this part documents that support.

 CHAPTER 29. Using Transact-SQL with SQL Anywhere

 CHAPTER 30. Transact-SQL Procedure Language

 CHAPTER 31. Using the Open Server Gateway


Using Transact-SQL with SQL Anywhere
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

About this chapter

This chapter is a guide for creating applications compatible with both SQL Anywhere and SQL Server. It describes SQL Anywhere support for Transact-SQL language elements and statements, and for SQL Server system tables, views, and procedures.

For information about using Transact-SQL-compatible procedures, triggers, and batches in SQL Anywhere, see the chapter "Transact-SQL Procedure Language".

Before you begin

If you are not concerned with SQL Server and Transact-SQL compatibility, you do not need to read this chapter.

 An overview of SQL Anywhere support for Transact-SQL

 SQL Server and SQL Anywhere architectures

 General guidelines for writing portable SQL

 Configuring SQL Anywhere for Transact-SQL compatibility

 Using compatible data types

 Local and global variables

 Building compatible expressions

 Using compatible functions

 Building compatible search conditions

 Other language elements

 Transact-SQL statement reference

 Compatible system catalog information

 SQL Server system and catalog procedures

 Implicit data type conversion


An overview of SQL Anywhere support for Transact-SQL
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

An overview of SQL Anywhere support for Transact-SQL

The Watcom-SQL dialect supported by SQL Anywhere database engines and servers is based on the ISO/ANSI standard. It conforms to the SQL 89 standard, and has many features defined in IBM's DB2 and SAA specification, as well as in ISO/ANSI SQL/92.

With this release, SQL Anywhere also supports the Sybase Transact-SQL dialect. This chapter describes the compatibility of the two dialects of SQL.

Goals

The goals of SQL Anywhere's Transact-SQL support are:

♦	To make applications and stored procedures portable. Many applications, stored procedures, and batch files can be written to be used with both SQL Server and SQL Anywhere databases.

♦	To make data portable. Data can be exchanged and replicated between SQL Anywhere and SQL Server databases with a minimum of effort.

The aim is to make it possible to write applications to work with both SQL Server and SQL Anywhere; existing SQL Server applications will generally require some changes to run on a SQL Anywhere database.

Two dialects in one database

The two dialects of SQL coexist in SQL Anywhere in the following way:

♦	Many SQL statements can be used in either of the two dialects.

♦	Where either dialect has an extension that does not conflict with the other dialect, either variant of a statement can be used.

♦	For groups of statements, as in procedures, triggers, and batches, you must use either the Transact-SQL or Watcom-SQL dialect (including statements common to both) throughout the procedure or batch. For example, each dialect has different flow control statements. You must use control statements from one dialect only throughout the batch or procedure.

The following diagram illustrates how the two dialects overlap.

Similarities and differences

SQL Anywhere supports a very high percentage of Transact-SQL language elements, functions, and statements for working with existing data. For example, all the numeric functions are supported, all but one of the string functions are supported, all aggregate functions are supported, and all date and time functions are supported. As another example, the Transact-SQL outer joins (using =* and *= operators) and extended DELETE and UPDATE statements using joins are supported in SQL Anywhere.

Further, a very high percentage of the Transact-SQL stored procedure language is supported (CREATE PROCEDURE and CREATE TRIGGER syntax, control statements, and so on). The stored procedure language is discussed in the chapter "Transact-SQL Procedure Language".

Many but not all aspects of Transact-SQL data definition language statements are supported.

There are more differences in the architectural and configuration facilities supported by each database. Device management, user management, and maintenance tasks such as backups tend to be system specific, and providing support for such tasks in a consistent manner is less important to most users. Even here, a set of Transact-SQL system tables is provided in SQL Anywhere as views, where the tables that are not meaningful in SQL Anywhere have no rows. Also, a set of system procedures is provided for some of the more common administrative tasks.

This chapter looks first at some system-level issues where differences are most marked, before discussing data manipulation and data definition language aspects of the dialects where compatibility is high.


SQL Server and SQL Anywhere architectures
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

SQL Server and SQL Anywhere architectures

SQL Server and SQL Anywhere are complementary products, with architectures designed to suit their distinct purposes. SQL Anywhere is designed as a workgroup or departmental server requiring little administration, and as a single-user database. SQL Server is designed as an enterprise-level server for the largest databases.

This section describes architectural differences between SQL Server and SQL Anywhere. It also describes the SQL Server-like tools SQL Anywhere includes for compatible database management.

 Servers and databases in SQL Server and SQL Anywhere

 System tables in SQL Anywhere and SQL Server

 Administrative roles in SQL Server and SQL Anywhere

 Users and groups in SQL Anywhere and SQL Server


Servers and databases in SQL Server and SQL Anywhere
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

SQL Server and SQL Anywhere architectures

Servers and databases in SQL Server and SQL Anywhere

The relationship between servers and databases is different in SQL Server and in SQL Anywhere.

In SQL Server, each database exists inside a server, and each server can contain several databases. Users are granted login rights to the server, and can connect to the server. They can then use each database on that server for which they have been granted permissions. There are system-wide system tables held in a master database that contain information common to all databases on the server.

In SQL Anywhere, there is no level corresponding to the SQL Server master database. In SQL Anywhere, each database is an independent entity, containing all its system tables. Users are granted connection rights to a database, not to the server. When a user connects, the connection is to an individual database. There is no system-wide set of system tables maintained at a master database level. Each SQL Anywhere database engine or server can dynamically load and unload multiple databases, and users can maintain independent connections on each, but there is no way of addressing more than one database from within a single connection.

SQL Anywhere provides tools in its Transact-SQL support and in its Open Server Gateway to allow some tasks to be carried out in a SQL Server-like manner. For example, SQL Anywhere provides an implementation of the SQL Server sp_addlogin system procedure that carries out the nearest equivalent action: adding a user to a database.


System tables in SQL Anywhere and SQL Server
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

SQL Server and SQL Anywhere architectures

System tables in SQL Anywhere and SQL Server

In addition to its own system tables, SQL Anywhere provides a set of system views that mimic relevant parts of the SQL Server system tables. These are listed and described individually in "Compatible system catalog information", which describes the system catalogs of the two products. This section provides a brief overview of the differences.

The SQL Anywhere system tables are held entirely within each database, while the SQL Server system tables are held partly inside each database and partly at the server level. The SQL Anywhere architecture does not include a level above the database.

In SQL Server, the system tables are owned by the database owner, user ID dbo. In SQL Anywhere, the system tables are owned by the system owner, user ID SYS. The SQL Server-compatible system views provided by SQL Anywhere are owned by a dbo user ID.


Administrative roles in SQL Server and SQL Anywhere
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

SQL Server and SQL Anywhere architectures

Administrative roles in SQL Server and SQL Anywhere

SQL Server has a more elaborate set of administrative roles than SQL Anywhere. In SQL Server the following are distinct roles, although more than one login account on a SQL Server can be granted any role, and one account can possess more than one role.

SQL Server roles

♦	The System Administrator is responsible for general administrative tasks unrelated to specific applications; can access any database object.

♦	The System Security Officer is responsible for security-sensitive tasks in SQL Server, but has no special permissions on database objects.

♦	The Database Owner has full permissions on objects inside the database that he or she owns, can add users to a database and can grant other users the permission to create objects and execute commands within the database.

♦	Permissions can be granted to users for specific data definition statements, such as CREATE TABLE or CREATE VIEW, enabling the user to use those statements to create database objects.

♦	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 SQL Anywhere the following database-wide permissions have administrative roles:

♦	The Database Administrator (DBA permissions) has, like the SQL Server database owner, full permissions on objects inside the database that he or she owns and can grant other users the permission to create objects and execute commands within the database. The default database administrator is user ID DBA. In SQL Anywhere, DBA is a reserved word and must have double quotes around it when used in object name qualifiers.

♦	The RESOURCE permission allows a user to create any kind of object within a database. This is instead of the SQL Server scheme of granting permissions on individual CREATE statements.

♦	SQL Anywhere has object owners in the same way that SQL Server does. The owner of an object automatically has all permissions on the object, including the right to grant permissions.

To ease seamless access to data held in both SQL Server and SQL Anywhere, you should create user IDs with appropriate permissions in the database (RESOURCE in SQL Anywhere, or permission on individual CREATE statements in SQL Server) and create objects from that user ID. If the same user ID is used in each environment, object names and qualifiers can be identical in the two databases, helping to ensure compatible access.


Users and groups in SQL Anywhere and SQL Server
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

SQL Server and SQL Anywhere architectures

Users and groups in SQL Anywhere and SQL Server

There are some differences between the SQL Server and SQL Anywhere models of users and groups. In SQL Server, connections are made 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 will access on that server. Each user of a database can be a member of at most one group. In SQL Anywhere, where connections are made to a database, there is nothing corresponding to the login ID. Instead, each user is granted a user ID and password on a database in order to use that database. Users can be members of many groups, and group hierarchies are allowed.

SQL Server and SQL Anywhere both allow user groups, to permit granting permissions to many users at one time. However, there are differences in the specifics of groups in the two products (for example, SQL Server allows each user to be a member of only one group, while SQL Anywhere has no such restriction). You should compare the documentation on users and groups in the two products for specific information.

Both SQL Server and SQL Anywhere have a public group, for defining default permissions. Every user is automatically a member of the public group.

SQL Anywhere supports the following SQL Server system procedures for managing users and groups.

For the arguments to each procedure, see "SQL Server system procedures":

System procedure	Description
sp_addlogin	In SQL Server, this adds a user to the server. In SQL Anywhere, this adds a user to a database
sp_adduser	In SQL Server and SQL Anywhere, this adds a user to a database. While this is a distinct task from sp_addlogin in SQL Server, in SQL 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 SQL Server, removes a user from the server. In SQL Anywhere, removes a user from the database
sp_dropuser	Removes a user from the database
sp_dropgroup	Removes a group from the database


General guidelines for writing portable SQL
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

General guidelines for writing portable SQL

When writing SQL that will be used on more than one database, you should be as explicit as possible in your SQL statements. Even if a given SQL statement is supported by more than one database engine, it may be a mistake to assume that default behavior when an option is not specified as the same on each engine. The following general guidelines apply when writing compatible SQL:

♦	Spell out all the available options, rather than assuming portable default behavior.

♦	Make the order of execution within statements explicit using parentheses, rather than assuming identical default order of precedence for operators.

♦	Use the Transact-SQL convention of an @ sign preceding variable names for SQL Server portability.

♦	In procedures, triggers, and batches, declare variables and cursors immediately following a BEGIN statement. This is required by SQL Anywhere, although SQL Server allows declarations to be made anywhere in a procedure, trigger, or batch.

♦	Avoid using keywords from either SQL Server or SQL Anywhere as identifiers in your databases.


Configuring SQL Anywhere for Transact-SQL compatibility
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Configuring SQL Anywhere for Transact-SQL compatibility

Some differences in behavior between the SQL Anywhere database engine and SQL Server can be eliminated by selecting appropriate options when creating a database or, if you are working on an existing database, when rebuilding the database. Other differences can be controlled by connection level options using the SET OPTION statement in SQL Anywhere or the SET statement in SQL Server.

 Creating a Transact-SQL-compatible database

 Setting options for Transact-SQL compatibility

 Case-sensitivity in SQL Server and SQL Anywhere databases

 Ensuring compatible object names


Creating a Transact-SQL-compatible database
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Configuring SQL Anywhere for Transact-SQL compatibility

Creating a Transact-SQL-compatible database

This section describes choices that must be made when a database is created or rebuilt.

Ignore trailing blanks in comparisons

When building a SQL Server-compatible database using SQL Anywhere, you should choose the option to ignore trailing blanks in comparisons.

♦	If you are using Sybase Central, this option is on the second page of the Create Database wizard.

♦	If you are using ISQL for OS/2 or Windows 3.x, this option is on the Create Database dialog box that appears when you select Create Database from the Database Tools window and click Create.

♦	If you are using the DBINIT command line utility, specify the -b command line switch.

With this option chosen, the following two strings are considered equal by both SQL Server and SQL Anywhere:

'ignore the trailing blanks   '

'ignore the trailing blanks'

If this option is not chosen, the two strings above are considered different by SQL Anywhere.

A side effect of this option is that strings are padded with blanks when fetched by a client application.

Ensure the dbo user ID is set

SQL Anywhere provides system views that mimic relevant parts of the SQL Server system tables. The owner of these views is, by default, the user ID dbo, as in SQL Server databases. If you have a database that already has a user ID named dbo, then you can transfer the ownership of these system views to another user ID. You can set the owner of the Transact-SQL system views as follows:

♦	If you are using Sybase Central, this option is on the second page of the Create Database wizard.

♦	If you are using ISQL for OS/2 or Windows 3.x, this option is on the Create Database dialog box which appears when you select Create Database from the Database Tools window and click Create.

♦	If you are using the DBINIT command line utility, specify the -g command line switch.

Remove historical system views

Older versions of Sybase SQL Anywhere employed two system views whose names conflict with the SQL Server system views provided for compatibility. These views are SYSCOLUMNS and SYSINDEXES. If you are not using Watcom SQL 4.0 and you are using the Open Server Gateway, you should 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 ;

 To drop the 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 views.


Setting options for Transact-SQL compatibility
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Configuring SQL Anywhere for Transact-SQL compatibility

Setting options for Transact-SQL compatibility

SQL Anywhere database options are set using the SET OPTION statement. Several database option settings are relevant to Transact-SQL behavior.

Set the allow_nulls_by_default option

By default, SQL Server does not allow NULLs on new columns unless they are explicitly declared to allow NULLs. SQL Anywhere permits NULLs in new columns by default, which is compatible with the SQL/92 ISO standard.

To make SQL Server 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 SQL 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, the SQL Server treatment of identifiers and of strings differs from the SQL Anywhere behavior, which matches the SQL/92 ISO standard.

The quoted_identifier option is available in both SQL Server and SQL Anywhere. You should ensure that 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 SQL Server and SQL Anywhere.

For Transact-SQL behavior, set the quoted_identifier option to OFF in both SQL Server and SQL Anywhere. If you choose this, you can no longer use double-quoted keywords in identifiers (such as the DBA user ID).

For more information on the quoted_identifier option, see "Compatibility of constants".

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 SQL Anywhere treatment of timestamp columns is more similar to SQL Server behavior.

With the automatic_timestamp option set to ON in SQL Anywhere (the default setting is OFF), any new columns with the TIMESTAMP data type that do not have an explicit default value defined are given 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 SQL Server and SQL Anywhere support the string_rtruncation option, which affects whether or not error messages are reported when an INSERT or UPDATE string is truncated. You should ensure that the option is set to the same value in each database.

  For more information on the string_rtruncation option, see "SET OPTION statement".

  For more information

For more information on database options for Transact-SQL compatibility, see "Transact-SQL SET statement".

If you are accessing a SQL Anywhere database using the Open Server Gateway, you can take advantage of actions that the Open Server Gateway performs on connection. These actions are listed in "Open Server Gateway actions on connecting".


Case-sensitivity in SQL Server and SQL Anywhere databases
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Configuring SQL Anywhere for Transact-SQL compatibility

Case-sensitivity in SQL Server and SQL Anywhere databases

The case-sensitivity of SQL Anywhere data in comparisons is decided when the database is created. By default, SQL Anywhere databases are case-insensitive in comparisons, although data is always held in the case in which it is entered.

SQL Anywhere does not support case sensitive identifiers.

SQL Server's sensitivity to the case (upper or lower) of identifiers and data depends on the sort order installed on the SQL Server. Case sensitivity can be changed for single-byte character sets by reconfiguring the SQL Server sort order.

In SQL Server, user-defined data type names are case sensitive. In SQL Anywhere, they are case insensitive.


Ensuring compatible object names
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Configuring SQL Anywhere for Transact-SQL compatibility

Ensuring compatible object names

Database objects must have a unique name within a certain name space. Outside this name space, duplicate names are allowed. There are some database objects that occupy different name spaces in SQL Server and SQL Anywhere.

In SQL 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.

SQL Server has a less restrictive name space for index names than SQL 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, you should stay within the SQL Anywhere restriction of unique index names for a given table owner.

SQL Server has a more restrictive name space on trigger names than SQL Anywhere. Trigger names must be unique in the database. For compatible SQL, you should stay within the SQL Server restriction and make your trigger names unique in the database.


Using compatible data types
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Using compatible data types

Although there are many data types that are common to SQL Server and SQL Anywhere, some data types are unique to each DBMS.

The following tables summarize the compatibility of data types between the two DBMS's. These tables are a guide only, and a marking of both may not mean that the data type performs in an identical manner for all purposes under all circumstances. For detailed descriptions, you should refer to the SQL Server documentation and chapter of this guide "Watcom-SQL Language Reference".

Differences between SQL Anywhere and SQL Server in how data types are stored are not discussed. Such differences do affect performance and resources, but not the syntax or semantics of supported SQL statements.

 Integer data types

 Decimal data types

 Compatibility of character data types

 Compatibility of binary data types

 Money data types

 Bit data type

 Compatibility of date and time data types

 The special Transact-SQL timestamp column and data type

 The special identity column

 Compatibility of user-defined data types


Integer data types
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Using compatible data types

Integer data types

Data type	Description	Supported by
INT	Signed integer	Both
INTEGER	Synonym for INT	Both
SMALLINT	2-byte integer	Both
TINYINT	<= 255	Both
Notes

♦	In SQL Anywhere Embedded SQL, TINYINT columns should be fetched into 2-byte or 4-byte integer columns. Also, to send a TINYINT value to a database the C variable should be an integer.

♦	In SQL Anywhere TINYINT columns should not be fetched into Embedded SQL 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.


Decimal data types
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Using compatible data types

Decimal data types

Data type	Description	Supported by
NUMERIC (p,s)	Exact decimal	Both
DECIMAL (p,s)	Synonym for NUMERIC*	Both
REAL	Single precision floating-point number	Both
DOUBLE	Double precision floating-point number	Both
FLOAT [ ( p ) ]	Synonym for REAL or DOUBLE	Both
Notes

♦	Only the NUMERIC data type with s = 0 can be used for the Transact-SQL identity column.

♦	You should avoid default precision and scale settings for numeric and decimal data types, as these are different in SQL Anywhere and SQL Server. In SQL Anywhere, the default setting is precision = 30 and scale = 6; in SQL Server, the default setting is precision = 18 and scale = 0.

♦	The FLOAT ( p ) data type is a synonym for REAL or DOUBLE, depending on the value of p. For SQL Server, REAL is used for p less than or equal to 15, and DOUBLE for p greater than 15. For SQL Anywhere, the cutoff is platform-dependent, but on all platforms the cutoff value is greater than 15.


Compatibility of character data types
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Using compatible data types

Compatibility of character data types

Data type	Description	Supported by
CHAR (n)	Character data of at most n characters	Both
CHARACTER (n)	Synonym for CHAR	SQL Anywhere
NCHAR(n)	As CHAR(n), but for multibyte sets	SQL Server
VARCHAR (n)	Variable length character data	Both
NVARCHAR(n)	As VARCHAR(n),  but for multibyte sets	SQL Server
LONG VARCHAR	Arbitrary length character data	SQL Anywhere
TEXT	Arbitrary length character data	Both
Notes

♦	TEXT is implemented in SQL Anywhere as a user-defined data type, as LONG VARCHAR allowing NULL.

♦	CHAR(n) fields in SQL Anywhere allow multi-byte strings.


Compatibility of binary data types
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Using compatible data types

Compatibility of binary data types

Data type	Description	Supported by
BINARY (n)	Binary data of maximum length n	both
LONG BINARY	Arbitrary length binary data.	SQL Anywhere
VARBINARY (n)	Binary data	SQL Server
IMAGE	Binary data	both
Notes

♦	IMAGE is implemented in SQL Anywhere as a user-defined data type, as LONG BINARY allowing NULL.


Money data types
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Using compatible data types

Money data types

Data type	Description	Supported by
MONEY	Currency data	Both
SMALLMONEY	Currency data	Both
Notes

♦	The MONEY data type is implemented in SQL Anywhere as a user-defined data type, as NUMERIC(20,4), allowing NULL.

♦	The SMALLMONEY data type is implemented in SQL Anywhere as a user-defined data type, as NUMERIC(10,4), allowing NULL.


Bit data type
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Using compatible data types

Bit data type

Data type	Description	Supported by
BIT	0 or 1	Both
Notes

♦	BIT is implemented in SQL Anywhere as a user-defined data type, as a TINYINT allowing NULL. Consequently, values other than 0 or 1 can be stored in BIT columns in SQL Anywhere. You should, however, avoid storing values other than 0 or 1 in BIT columns.


Compatibility of date and time data types
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Using compatible data types

Compatibility of date and time data types

Data type	Description	Supported by
DATETIME	Date and time information	both
TIMESTAMP	Date and time information	SQL Anywhere: similar to DATETIME
SMALLDATETIME	Dates and times, accurate to a minute	both
TIME	Time of day	SQL Anywhere
DATE	Year, month and day	SQL Anywhere
Notes

♦	The SQL Anywhere data type TIMESTAMP is not the same as the special TIMESTAMP column in Transact-SQL.

♦	The DATETIME and SMALLDATETIME data types are implemented in SQL Anywhere as user-defined data type. They are defined as TIMESTAMP data types.


The special Transact-SQL timestamp column and data type
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Using compatible data types

The special Transact-SQL timestamp column and data type

SQL Anywhere supports the Transact-SQL special timestamp column. The timestamp column is used together with the tsequal system function to check whether a row has been updated.

Two meanings of timestamp—SQL Anywhere has a TIMESTAMP data type, which holds accurate date and time information. This is distinct from the special Transact-SQL TIMESTAMP column and data type.

Creating a Transact-SQL timestamp column in SQL Anywhere

To create a Transact-SQL timestamp column, create a column that has the (SQL Anywhere) data type TIMESTAMP and has a default setting of timestamp. The column can have any name, although the name timestamp is commonly used.

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 SQL Server a column with the name timestamp and no data type specified is automatically given a TIMESTAMP data type. In SQL Anywhere you must explicitly assign the data type yourself.

If you have the AUTOMATIC_TIMESTAMP database option set to ON, then you do not need to set the default value: any new column created with TIMESTAMP data type and with no explicit default is given 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

SQL Server treats a timestamp column as a user-defined data type that is VARBINARY(8), allowing NULL, while SQL 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 way the column is described.

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 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 ISQL, 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, and when an UPDATE of one of the selected rows is submitted, it can use the tsequal function to check that the row has not been changed. The tsequal function compares the timestamp value in the table with the timestamp value obtained in the SELECT. If they are the same, the row has not been changed; if they differ, the row has been changed since the SELECT was carried out.

The following is a typical UPDATE statement using the tsequal function:

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
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Using compatible data types

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 maximum number of rows that may be inserted into the table.

The identity column is used to store sequential numbers, such as invoice numbers or employee numbers, that are generated automatically by SQL Anywhere. The value of the identity column uniquely identifies each row in a table.

In SQL Server, 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 SQL Anywhere, the identity column is implemented as a column default setting. Values that are not part of the sequence may be explicitly inserted into the column with an INSERT statement. SQL Server does not allow INSERTs into identity columns unless the identity_insert option is set to on. In SQL Anywhere, you need to set the NOT NULL property yourself and ensure that no more than one column is an identity column. SQL Anywhere allows any numeric data type to be used as an identity column.

The first time you insert a row into the table, SQL Anywhere assigns a value of 1 to an identity column. On each subsequent insert, the value of the column is incremented by one. The value most recently inserted into an identity column is available in the @@identity global variable.

In SQL Anywhere the identity column is identical to the AUTOINCREMENT default setting for a column.


Compatibility of user-defined data types
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Using compatible data types

Compatibility of user-defined data types

SQL Anywhere supports user-defined data types. For a general description, see "User-defined data types" and for syntax of the SQL statement, see "CREATE DATATYPE statement".

In SQL Anywhere, user-defined data types 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.

You can use the sp_addtype system procedure to add a user-defined data type, or you can use the CREATE DATATYPE statement.


Local and global variables
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Local and global variables

Local 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. 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 engine. Users cannot define global variables.

 Local variable support

 Global variable support

 Obtaining the values of variables


Local variable support
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Local and global variables

Local variable support

SQL Server and SQL Anywhere both support local variables. In Transact-SQL all variables must be prefixed with an @ sign. In SQL Anywhere the @ prefix is optional. To write compatible SQL, ensure all your variables have the @ prefix.

Scope of local variables

The scope of local variables is different in SQL Anywhere and SQL Server.

SQL Anywhere provides two kinds of local variables:

♦	You can use the DECLARE statement at the beginning of a compound statement to declare a variable. The variable exists within the compound statement only.

♦	You can use the CREATE VARIABLE statement to create a variable that exists for the connection.

SQL Server local variables are declared using the DECLARE statement, and exist for the duration of the batch in which they are declared.

SQL Anywhere supports the DECLARE statement to declare local variables within a batch. However, if the DECLARE is executed within a compound statement, it does not exist outside the compound statement.

For more information on batches and local variable scope, see "Variable and cursor declarations".


Global variable support
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Local and global variables

Global variable support

The following list includes all SQL Server global variables supported in SQL Anywhere. SQL Server global variables not supported by SQL Anywhere are not included in the list. All the listed global variables return a value, but in some cases that value is fixed at NULL, 1, -1, or 0, and may not be meaningful. This is indicated in the list.

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	Returns
@@char_convert	Returns 0
@@client_csname	In SQL Server, 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 SQL Anywhere
@@client_csid	In SQL Server, 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 SQL Anywhere
@@connections	The number of logins since the server was last started
@@cpu_busy	In SQL Server, the amount of time, in ticks, that the CPU has spent doing SQL Server work since the last time SQL Server was started. In SQL 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. @@identity 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
@@idle	In SQL Server, the amount of time, in ticks, that SQL Server has been idle since it was last started. In SQL Anywhere returns 0
@@io_busy	In SQL Server, amount of time, in ticks, that SQL Server has spent doing input and output operations since it was last started. In SQL Anywhere, returns 0
@@isolation	Current isolation level of the connection. In SQL Server, @@isolation takes the value of the active level
@@langid	In SQL Server, defines the local language id of the language currently in use. In SQL Anywhere, returns 0
@@language	In SQL Server, defines the name of the language currently in use. In SQL Anywhere, returns "English"
@@maxcharlen	In SQL Server, maximum length, in bytes, of a character in SQL Server's default character set. In SQL Anywhere, returns 1
@@max_connections	For the standalone engine, the maximum number of simultaneous connections that can be made to the engine, which is 10. For the network server, the maximum number of active clients (not of database connections, as each client can support multiple connections). For SQL Server, the maximum number of connections to the server.
@@ncharsize	In SQL Server, average length, in bytes, of a national character. In SQL Anywhere, returns 1
@@nestlevel	In SQL Server, 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 SQL Anywhere, returns -1
@@pack_received	In SQL Server, number of input packets read by SQL Server since it was last started. In SQL Anywhere, returns 0
@@pack_sent	In SQL Server, number of output packets written by SQL Server since it was last started. In SQL Anywhere, returns 0
@@packet_errors	In SQL Server, number of errors that have occurred while SQL Server was sending and receiving packets. In SQL Anywhere, returns 0.
@@procid	Stored procedure ID of the currently executing procedure
@@rowcount	Number of rows affected by the last command. @@rowcount is set to zero by any command which does not return rows, such as an if statement. 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 SQL Server or SQL Anywhere server
@@spid	In SQL Server, server process ID number of the current process. In SQL 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
@@thresh_hysteresis	In SQL Server, change in free space required to activate a threshold. In SQL Anywhere, returns 0
@@timeticks	In SQL Server, number of microseconds per tick. The amount of time per tick is machine dependent. In SQL Anywhere, returns 0
@@total_errors	In SQL Server, number of errors that have occurred while SQL Server was reading or writing. In SQL Anywhere, returns 0.
@@total_read	In SQL Server, number of disk reads by SQL Server since it was last started. In SQL Anywhere, returns 0
@@total_write	In SQL Server, number of disk writes by SQL Server since it was last started. In SQL Anywhere, returns 0
@@tranchained	Current transaction mode of the Transact-SQL program. @@tranchained returns a 0 for unchained or a 1 for chained.
@@trancount	Nesting level of transactions. Each begin transaction in a batch increments the transaction count.   For details, see "Transact-SQL BEGIN TRANSACTION statement"
@@transtate	In SQL Server, current state of a transaction after a statement executes. In SQL Anywhere, returns -1
@@version	Information on the current version of SQL Server or SQL Anywhere


Obtaining the values of variables
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Local and global variables

Obtaining the values of variables

You can use a SELECT statement with an empty table list to display the values of variables. For example, the following statement returns the value of the global variable @@version:

SELECT @@version

For more information on the SELECT statement, see "Transact-SQL SELECT statement".


Building compatible expressions
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Building compatible expressions

The following table describes the compatibility of expressions between SQL Server and SQL 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 SQL Server documentation and the SQL Anywhere User's Guide.

In the table, expr is short for expression, and op is short for operator. Further description of each kind of expression is given in subsequent subsections.

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	SQL Anywhere
For more information on compatibility of constants, see "Compatibility of constants". For more information on compatibility of operators, see "Compatibility of operators".

 Compatibility of constants

 Compatibility of operators


Compatibility of constants
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Building compatible expressions

Compatibility of constants

Constant	Supported by
integer	Both
number	Both
'string'	Both
special-constant	Both
host-variable	SQL Anywhere
Default interpretation of delimited strings

By default, SQL Server and SQL Anywhere give different meanings to delimited strings: that is, strings enclosed in apostrophes (single quotes) and in quotation marks (double quotes).

SQL 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). SQL Server 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

Both SQL Server and SQL 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 SQL Server, and to ON in SQL Anywhere.

While the Transact-SQL SET statement is not supported for most SQL Server connection options, it is supported for the quoted_identifier option.

The following statement in either SQL Anywhere or SQL Server changes the setting of the quoted_identifier option to ON:

SET quoted_identifier ON

With the quoted_identifier option set to ON, SQL Server allows table, view, and column names to be delimited by quotes. Other object names cannot be delimited in SQL Server.

The following statement in SQL Anywhere or SQL Server 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 SQL Server and SQL Anywhere as long as the quoted_identifier option is set to the same value in each DBMS.

Examples

If you choose to operate with the quoted_identifier option on (the default SQL Anywhere setting), then the following statements involving the SQL keyword user are valid for both DBMS's.

CREATE TABLE "user" (

   col1 char(5)

) ;

INSERT "user" ( col1 )

VALUES ( 'abcde' ) ;

If you choose to operate with the quoted_identifier option off (the default SQL Server setting), then the following statements are valid for both DBMS's.

SELECT *

FROM employee

WHERE emp_lname = "Chin"

You cannot use SQL keywords as identifiers if the quoted_identifier option is off.


Compatibility of operators
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Building compatible expressions

Compatibility of operators

The following tables describe the compatibility of operators between SQL Server and SQL 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 SQL Server documentation and the SQL Anywhere User's Guide.

Arithmetic operators

Operator	Description	Supported by
+	addition	Both
-	subtraction	Both
*	multiplication	Both
/	division	Both
%	modulo operator	SQL Server
Notes

♦	While SQL Anywhere does not provide the % operator, it does provide a MOD function. MOD(21,11) in SQL Anywhere is the same as 21 % 11 in Transact-SQL.

♦	SQL Anywhere treats % as a comment delimiter.

String concatenation operator

Operator	Supported by
+	Both
||	SQL Anywhere
Notes

♦	When using the + concatenation operator in SQL Anywhere, you should ensure the operands are explicitly set to strings 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

Operator	Description	Supported by
&	and	Both
|	or	Both
^	exclusive or	Both
~	not	Both
Join operators

The Transact-SQL outer join operators *= and =* are supported in SQL Anywhere, in addition to the SQL/92 join syntax using a table expression in the FROM clause.

Operator precedence

When using 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 the two database engines.


Using compatible functions
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Using compatible functions

The following tables describe the compatibility of functions between SQL Server and SQL Anywhere. These tables are a guide only, and a marking of both may not mean that the function performs in an identical manner for all purposes under all circumstances. For detailed descriptions, you should refer to the SQL Server documentation and the section "Watcom-SQL Functions".

 Compatibility of aggregate functions

 Compatibility of numeric functions

 Compatibility of string functions

 Compatibility of date and time functions

 Compatibility of data type conversion functions

 Compatibility of miscellaneous functions

 Compatibility of text and image functions

 Compatibility of system functions


Compatibility of aggregate functions
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Using compatible functions

Compatibility of aggregate functions

Function	Supported by
COUNT(*)	Both
COUNT	Both
LIST	SQL Anywhere
AVG	Both
MAX	Both
MIN	Both
SUM	Both


Compatibility of numeric functions
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Using compatible functions

Compatibility of numeric functions

In the following table, a and b are numeric expressions, and n is an integer expression.

Function	Description	Supported by
ABS (a)	Absolute value of a	Both
ACOS (a)	Arc cosine of a, in radians	Both
ASIN (a)	Arc sine of a, in radians	Both
ATAN (a)	Arc tangent of a, in radians	Both
ATN2 (a,b)	Arc tangent of a/b, in radians	Both
CEILING (a)	Smallest integer not less than a	Both
COS (a)	Cosine of a, with a in radians	Both
COT (a)	Cotangent of a, with a in radians	Both
DEGREES (a)	Converts radians to degrees	Both
EXP (a)	Exponential function of a	Both
FLOOR (a)	Largest integer not greater than a	Both
LOG (a)	Natural logarithm of a	Both
LOG10 (a)	Logarithm base 10 of a	Both
MOD (a, b)	Remainder when a is divided by b	SQL Anywhere
PI()	Numeric value Pi	Both
POWER (a,b)	a to the power b	Both
RADIANS (a)	Converts degrees to radians	Both
RAND ([n])	Random number between 0 and 1	Both
ROUND (a,n)	Rounds a to n places	Both
REMAINDER(a,b)	Same as MOD	SQL Anywhere
SIGN (a)	Sign of a	Both
SIN (a)	Sine of a, with a in radians	Both
SQRT (a)	Square root of a	Both
TAN (a)	Tangent of a, with a in radians	Both
TRUNCATE (a, n)	Truncate a to n places	SQL Anywhere
Notes

♦	In addition to PI(), SQL Anywhere also uses PI(*).

♦	The value of n in ROUND and TRUNCATE is relative to the decimal point. Negative numbers are to the left of the decimal point.


Compatibility of string functions
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Using compatible functions

Compatibility of string functions

In the following, s is a string expression, and n is an integer expression.

Function	Description	Supported by
ASCII(s)	Integer ASCII value of first character in s	Both
CHAR(n)	Character with ASCII value n	Both
CHARINDEX (s1,s2)	Offset of s1 in s2	Both
DIFFERENCE (s1,s2)	Difference between two soundex values	Both
INSERTSTR(n,s1,s2)	Inserts s2 into s1 at n	SQL Anywhere
LCASE(s)	Converts s to lower case	SQL Anywhere
LOWER(s)	Converts s to lower case	Both
LEFT(s,n)	Leftmost n characters in s	Both
LENGTH(s)	Number of characters in s	Both
LOCATE(s1, s2[,n])	Offset of s2 in s1, starting at n	SQL Anywhere
LTRIM(s)	Removes leading blanks	Both
PATINDEX (...)	Integer representing starting position of first occurrence of a pattern in s	Both
PLAN(s)	Optimization strategy of the SELECT statement s	SQL Anywhere
REPLICATE (S,n)	Concatenates strings	Both
RIGHT(s,n)	Rightmost n characters in s	Both
RTRIM( s)	Removes trailing blanks	Both
SIMILAR(s1, s2)	An integer representing similarity between s1 and s2	SQL Anywhere
SOUNDEX(s)	A number representing the sound of s	Both
SPACE (n)	Returns n spaces	Both
STR(n)	String representation of n	SQL Server
STRING(s1,...)	Concatenates and converts to strings	SQL Anywhere
STUFF (...)	Deletes and inserts characters	SQL Server
SUBSTR(s, n1, n2)	Substring of s starting at n1, of length n2	SQL Anywhere
SUBSTRING(s,n1,n2)	Substring of s starting at n1, of length n2	Both
TRACEBACK(*)	Traceback of procedures and triggers executing when the most recent error occurred.	SQL Anywhere
TRIM(*)	Removes leading and trailing blanks	SQL Anywhere
UCASE(s)	Converts s to upper case	SQL Anywhere
UPPER(s)	Converts s to upper case	Both
Notes

♦	The SQL Server SOUNDEX and DIFFERENCE return a four-character code, while SQL Anywhere returns an integer.


Compatibility of date and time functions
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Using compatible functions

Compatibility of date and time functions

The arguments are not listed in the date and time function tables. The Transact-SQL date and time functions are now supported as alternatives to SQL Anywhere's own functions. For full descriptions, see the SQL Server and SQL Anywhere documentation.

Date and time functions

Function	Description	Supported by
getdate	Current system date and time	both
datename	Name of part of the datetime value	both
datepart	Value of part of the datetime value	both
datediff	Datetime difference	both
dateadd	Adds datetime parts to the date	both
These date and time functions are used as follows:

♦	getdate ()   Returns the current date and time. The following aexample displays the system date and time.

SELECT getdate()

♦	datename ( datepart, date )   Returns the name of the specified part (such as the month "June") of a DATETIME value, as a character string. If the result is numeric, such as 23 for the day, it is still returned as a character string. For example, the following statement displays the value May.

SELECT datename( month , '1987/05/02' )

♦	datepart( datepart, date )   Returns an integer value for the specified part of a DATETIME value. For example, the following statement displays the value 5.

SELECT datepart( month , '1987/05/02' )

♦	datediff( datepart, date1, date2 )   Returns date2 - date1, measured in the specified date part. For example, the following statement displays the value 102.

SELECT datediff( month, '1987/05/02', '1995/11/15')

♦	dateadd( datepart, numeric_expression, date )   Returns the date produced by adding the specified number of the specified date parts to the date. The numeric_expression can be any numeric type; the value is truncated to an integer. For example, the following statement displays 1995-11-02 00:00:00.000.

SELECT dateadd( month, 102, '1987/05/02' )

The following table displays allowed values of datepart.

Date Part	Abbreviation	Values
year	yy	1753 - 9999
quarter	qq	1 - 4
month	mm	1 - 12
week	wk	1 - 54
day	dd	1 - 31
dayofyear	dy	1 - 366
weekday	dw	1 - 7 (Sun.-Sat.)
hour	hh	0 - 23
minute	mi	0 - 59
second	ss	0 - 59
millisecond	ms	0 - 999
SQL Anywhere date and time functions

Function	Description	Supported by
YEAR[S] form 1	Year of the given date	SQL Anywhere
YEARS form 2	Date difference, as number of whole years	SQL Anywhere
YEARS form 3	Adds dates, as number of whole years	SQL Anywhere
MONTH[S] form 1	Month of the given date	SQL Anywhere
MONTHS form 2	Date difference, as number of whole months	SQL Anywhere
MONTHS form 3	Adds dates, as number of whole months	SQL Anywhere
WEEK[S] form 1	Week of the given date	SQL Anywhere
WEEKS form 2	Date difference, as number of whole weeks	SQL Anywhere
WEEKS form 3	Adds dates, as number of whole weeks	SQL Anywhere
DAY[S] form 1	Day of the given date	SQL Anywhere
DAYS form 2	Date difference, as number of whole days	SQL Anywhere
DAYS form 3	Adds dates, as number of whole days	SQL Anywhere
DOW	Day of the week	SQL Anywhere
HOUR[S] form 1	Hour of the given date/time	SQL Anywhere
HOURS form 2	Date/time difference, as number of whole hours	SQL Anywhere
HOURS form 3	Adds date/times, as number of whole hours	SQL Anywhere
MINUTE[S] form 1	Minute of the given date/time	SQL Anywhere
MINUTES form 2	Date/time difference, as number of whole minutes	SQL Anywhere
MINUTES form 3	Adds date/times, as number of whole minutes	SQL Anywhere
SECOND[S] form 1	Second of the given date/time	SQL Anywhere
SECONDS form 2	Date/time difference, as number of whole seconds	SQL Anywhere
SECONDS form 3	Adds date/times, as number of whole seconds	SQL Anywhere
NOW(*)	Current date and time	SQL Anywhere
TODAY(*)	Today's date	SQL Anywhere


Compatibility of data type conversion functions
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Using compatible functions

Compatibility of data type conversion functions

Both SQL Anywhere and SQL Server convert many data types implicitly, without the need to call a function to carry out the conversion. Both also provide explicit functions to carry out conversions.

Function	Description	Supported by
convert(datatype, expr [,style])	Converts expr to datatype	Both
hextoint (s)	Returns the integer equivalent of a hexadecimal string.	Both
inttohex (n)	Returns the hexadecimal equivalent of an integer	Both
The CONVERT function takes two or three arguments:

CONVERT (datatype, expression [,format-style])

The value expression is converted into data type datatype. The optional third parameter, format-style is the display format to use for the converted data (if converting to a date or time) or for the input data (if converting from a date or time). This is used for money data types (not supported for CONVERT in SQL Anywhere) and for datetime data types converted to strings to distinguish between, for example, May 2, 1987 and 1987/05/02. The format-style argument is a style code in the range 0 through 12 or 100 through 112, describd in the following table. A value greater than 100 produces a four-character year (yyyy) while values less than 100 yield a two-character year (yy). In the table, the two-character year is shown.

(yy)	(yyyy)	Output
0	0 or 100	mon dd yyyy hh:miAM (or PM)
1	101	mm/dd/yy
2	102	yy.mm.dd
3	103	dd/mm/yy
4	104	dd.mm.yy
5	105	dd-mm-yy
6	106	dd mon yy
7	107	mon dd, yy
8	108	hh:mm:ss
-	9 or 109	mmm dd yyyy hh:mi:ss:mmmAM (or PM)
10	110	mm-dd-yy
11	111	yy/mm/dd
12	112	yymmdd
The following statements illustrate the use of these format styles:

SELECT CONVERT( CHAR( 20 ), order_date, 104 )

FROM sales_order

order_date

16.03.1993

20.03.1993

23.03.1993

25.03.1993

SELECT CONVERT( CHAR( 20 ), order_date, 7 )

FROM sales_order

order_date

mar 16, 93

mar 20, 93

mar 23, 93

mar 25, 93

The additional data type conversion functions supported by SQL Anywhere are as follows:

Function	Description
DATE (expr)	Converts the expression to a date
DATETIME (expr)	Converts the expression to a timestamp
DATEFORMAT (date, expr)	Converts a date to a string using the format specified by expr
YMD( ny, nm, nd)	Returns a date value corresponding to the supplied year, month, and day values
CAST( expr AS -datatype )	Converts expr to data-type
STRING (expr)	Converts expr to a string


Compatibility of miscellaneous functions
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Using compatible functions

Compatibility of miscellaneous functions

SQL Anywhere supports a set of functions that do not fit neatly into any of the above categories.

Function	Description
ARGN ( n, expr-list )	Returns the n'th expression in expr-list
COALESCE ( expr-list )	The value of the first expression that is not NULL.
IFNULL ( a, b, c )	If a is null, returns b. If a is not null, then c.
ISNULL ( expr-list )	Same as COALESCE.
NUMBER( * )	Generates numbers starting at 1.
Notes

♦	These miscellaneous functions are not supported by SQL Server.


Compatibility of text and image functions
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Using compatible functions

Compatibility of text and image functions

The SQL Server textptr function is supported by SQL Anywhere. The syntax is:

textptr ( text_columname )

The function returns the text pointer value, a 16-byte binary value.

The SQL Server textvalid function is not currently supported by SQL Anywhere.


Compatibility of system functions
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Using compatible functions

Compatibility of system functions

The following table shows the SQL Server system functions and their status in SQL Anywhere:

Function	Status
col_length	Implemented
col_name	Implemented
db_id	Implemented
db_name	Implemented
index_col	Implemented
object_id	Implemented
object_name	Implemented
proc_role	Always returns 0
show_role	Always returns NULL
tsequal	Implemented
user_id	Implemented
user_name	Implemented
suser_id	Implemented
suser_name	Implemented
datalength	Implemented
curunreservedpgs	Not implemented
data_pgs	Not implemented
host_id	Not implemented
host_name	Not implemented
lct_admin	Not implemented
reserved_pgs	Not implemented
rowcnt	Not implemented
used_pgs	Not implemented
valid_name	Not implemented
valid_user	Not implemented
Notes

♦	Some of the system functions are implemented in SQL 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
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
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 SQL Anywhere user ID
user_name( [user-id] )	Returns the user ID (user name in SQL Server)
suser_id( [user-name] )	Returns an integer user identification number
suser_name( [user-id] )	Returns the user ID (server user name in SQL Server)
datalength( expression )	Returns the length of expression in bytes


Building compatible search conditions
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Building compatible search conditions

Search conditions are used in WHERE clauses, ON clauses (in SQL Anywhere), and in HAVING clauses to qualify or disqualify rows or groups from appearing in the result set. A search condition is a combination of expressions that has a value of TRUE, FALSE, or UNKNOWN.

Compatibility of expressions is the subject of "Building compatible expressions". For a search condition to be compatible, the expression or expressions of which it is composed must be compatible. This section assumes the expressions are compatible.

There are several kinds of conditions, which are discussed in the following sections.

♦	Comparison conditions

♦	BETWEEN and LIKE conditions

♦	IN conditions

♦	ALL or ANY conditions

♦	EXISTS conditions

♦	IS NULL conditions

♦	Conditions with logical operators, including AND and OR

 Compatibility of comparison conditions

 Compatibility of comparison operators

 Compatibility of BETWEEN and LIKE conditions

 Compatibility of IN conditions

 Compatibility of ALL and ANY conditions

 Compatibility of EXISTS conditions

 Compatibility of IS NULL conditions

 Providing estimates for conditions

 Conditions using logical operators


Compatibility of comparison conditions
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Building compatible search conditions

Compatibility of comparison conditions

Comparison conditions take the form

expression comparison-operator expression

The comparison operators are generally compatible between SQL Server and SQL Anywhere.


Compatibility of comparison operators
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Building compatible search conditions

Compatibility of comparison operators

Operator	Description	Supported by
=	Equal to	Both
>	Greater than	Both
<	Less than	Both
>=	Greater than or equal to	Both
<=	Less than or equal to	Both
<>	Not equal to	Both
!=	Not equal to	Both
!>	Not greater than	Both
!<	Not less than	Both
Trailing blanks in character data are ignored for comparison purposes by SQL Server. The behavior of SQL Anywhere when comparing strings is controlled by an option when creating the database.

For more information, see "Configuring SQL Anywhere for Transact-SQL compatibility".


Compatibility of BETWEEN and LIKE conditions
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Building compatible search conditions

Compatibility of BETWEEN and LIKE conditions

The BETWEEN condition is of the form

expr [NOT] BETWEEN start-expr AND end-expr

and is compatible with both SQL Server and SQL Anywhere.

The LIKE condition is of the form

expression [NOT] LIKE pattern [ESCAPE escape-expr]

The ESCAPE clause can be used to cause characters that otherwise take on a special meaning in a search pattern to be treated literally in the comparison. The ESCAPE clause is supported by SQL Anywhere only.

The pattern consists of characters and special wildcard characters that match one or more characters in a string. The pattern may be made up from variables, constants, and expressions.

SQL Anywhere supports the same pattern matching that is supported by SQL Server, using the following wild cards:

♦	underscore (_)   Matches any character

♦	percent (%)   Matches any string of zero or more characters

♦	[ ]   Matches sets or ranges of characters

For more information on these conditions, see the section "LIKE conditions".


Compatibility of IN conditions
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Building compatible search conditions

Compatibility of IN conditions

The IN condition tests if an expression equals any of a set of listed values. The IN condition is of the form:

expression [NOT] IN ( value-expr1 [, value-expr2 ] ... )

or

expression [NOT] IN ( subquery )

IN conditions are compatible between SQL Server and SQL Anywhere.


Compatibility of ALL and ANY conditions
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Building compatible search conditions

Compatibility of ALL and ANY conditions

The ALL and ANY conditions test an expression against the results of a subquery. The ALL and ANY conditions take the form:

expression comparison-operator { ANY | ALL } (subquery)

ANY and ALL subqueries are compatible between SQL Server and SQL Anywhere. SQL Anywhere supports SOME as a synonym for ANY.


Compatibility of EXISTS conditions
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Building compatible search conditions

Compatibility of EXISTS conditions

The EXISTS condition returns TRUE if a subquery result contains at least one row, and FALSE if the subquery result contains no rows. The EXISTS condition is of the form:

EXISTS (subquery)

The EXISTS condition is implemented in both SQL Server and SQL Anywhere.


Compatibility of IS NULL conditions
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Building compatible search conditions

Compatibility of IS NULL conditions

Expressions can be tested to see if they are NULL using the IS [NOT] NULL condition. The IS [NOT] NULL condition is implemented in both SQL Server and SQL Anywhere.

The NOT NULL condition is of the form

expression IS [NOT] NULL


Providing estimates for conditions
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Building compatible search conditions

Providing estimates for conditions

SQL Anywhere supports estimates of the percentage of rows that satisfy a condition, to assist in improving query performance. An estimate on a search condition is supplied as follows:

( condition, estimate )

SQL Server does not support explicit estimates.


Conditions using logical operators
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Building compatible search conditions

Conditions using logical operators

Logical operators include NOT: a compatible unary operator which takes the following form:

NOT condition

The NOT operator is compatible between SQL Server and SQL Anywhere.

Logical operators also include operators which test explicitly for the value of a condition:

condition IS [NOT] { TRUE | FALSE | UNKNOWN }

These operators are supported by SQL Anywhere only.

Logical operators also include the AND and OR operators, which allow search conditions to be combined. These combined conditions take the following form:

condition { AND | OR } condition

The AND and OR operators are supported by both SQL Server and SQL Anywhere. When more than one logical operator is used in a statement, AND operators are evaluated before OR operators by default. You can change the order of precedence with parentheses.


Other language elements
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Other language elements

This section describes language elements other than those described in the preceding sections.

 Compatible comment indicators


Compatible comment indicators
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Other language elements

Compatible comment indicators

In SQL Anywhere, you can use one of several identifiers to mark off comments in SQL statements.

SQL Anywhere now supports the following comment indicators:

♦	-- (Double hyphen.)   Any remaining characters on the line are ignored by the database engine. This is the SQL/92 comment indicator.

♦	% (Percent sign.)   The percent sign has the same meaning as the double hyphen.

♦	// (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. Of these comment markers, the double-hyphen style and the slash-asterisk style are compatible with Transact-SQL.


Transact-SQL statement reference
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Transact-SQL statement reference

This section describes the supported syntax of Transact-SQL statements.

Many SQL statements are common to Watcom-SQL and Transact-SQL, and for information on these, you should look in the chapter "Watcom-SQL Language Reference".

This section contains the following, in alphabetical order:

♦	Syntax description of statements implemented primarily for Transact-SQL compatibility, and for which there are alternatives in the Watcom-SQL dialect. For example, the READ TEXT statement is a Transact-SQL statement for which the SQL Anywhere GET DATA statement is an alternative.

♦	Syntax description for statements implemented primarily for Transact-SQL compatibility, and which are different in approach to the ISO/ANSI standard on which Watcom-SQL is based. For example, the BEGIN TRANSACTION statement introduces some functionality that Watcom-SQL does not have, but results in not all COMMIT statements making changes to the database permanent, which is contrary to ISO/ANSI behavior.

♦	Comments on statements documented in the chapter "Watcom-SQL Language Reference", for which the Transact-SQL syntax is different.

♦	Comments on some unsupported Transact-SQL statements, with pointers to the ways in which SQL Anywhere implements similar functionality. For example, the CREATE DEFAULT and CREATE RULE statements available in SQL Server are not supported in SQL Anywhere, but similar functionality is provided in the Watcom-SQL CREATE DATATYPE statement.

This section is a guide to the SQL supported by SQL Server and SQL Anywhere; it is not an exhaustive comparison. For those creating applications that must work with both SQL Server and SQL Anywhere, you should directly compare the descriptions of supported syntax in "Watcom-SQL Statements" and in this section against the SQL Server documentation.

Even though they are documented separately, you can use statements documented in this section together with Watcom-SQL statements.

Statements that are part of the Transact-SQL procedure language are documented separately. This includes control statements (IF, WHILE, and so on), CREATE PROCEDURE and CREATE TRIGGER statements, and other statements used primarily in procedures and triggers, such as RAISERROR. For information on these statements, see the chapter "Transact-SQL Procedure Language".

 Transact-SQL BEGIN TRANSACTION statement

 Transact-SQL COMMIT statement

 Transact-SQL CREATE DEFAULT and CREATE RULE statements

 Transact-SQL CREATE INDEX statement

 Transact-SQL CREATE MESSAGE statement

 Transact-SQL CREATE SCHEMA statement

 Transact-SQL CREATE TABLE statement

 Transact-SQL DATABASE statements

 Transact-SQL DELETE statement

 Transact-SQL DISK statements

 Transact-SQL GRANT and REVOKE statements

 Transact-SQL INSERT statement

 Transact-SQL joins

 Transact-SQL READTEXT statement

 Transact-SQL ROLLBACK statement

 Transact-SQL SELECT statement

 Transact-SQL SET statement

 Transact-SQL UPDATE statement

 Transact-SQL WRITETEXT statement


Transact-SQL BEGIN TRANSACTION statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Transact-SQL statement reference

Transact-SQL BEGIN TRANSACTION statement

Syntax

BEGIN TRAN[SACTION] [ transaction-name ]

Purpose

To begin a user-defined transaction.

Usage

Anywhere.

Authorization

None.

Side effects

None.

Description

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.

Chained and unchained modes

SQL Server and SQL Anywhere both have two transaction modes. The default SQL Server transaction mode, called unchained mode, commits each statement individually, unless an explicit BEGIN TRANSACTION statement is executed to start a transaction.

SQL Anywhere supports both chained and  unchained modes. You can control the mode by setting the CHAIN database option. The default setting in SQL Anywhere is ON, in which case SQL Anywhere runs in the ISO SQL/92 compatible chained mode. The default for SQL Server is that CHAINED be set to 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 about the CHAINED option and the chained mode, see "SET OPTION statement".

The current nesting level is held in the global variable @@trancount. The @@trancount variable has a value of zero before a 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.

@@trancount values in SQL Server and SQL Anywhere

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 SQL Server starts a transaction implicitly, the @@trancount variable is set to 1. SQL Anywhere does not set the @@trancount value to 1 when a transaction is started implicitly. Consequently, the SQL Anywhere @@trancount variable has a value of zero before any BEGIN TRANSACTION statement, (even though there is a current transaction), while in SQL Server (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 SQL Anywhere and SQL Server after the 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 1 in SQL Anywhere, and a value of 2 in SQL Server after the BEGIN TRANSACTION statement.


Transact-SQL COMMIT statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Transact-SQL statement reference

Transact-SQL COMMIT statement

Syntax

COMMIT TRAN[SACTION] [ transaction-name ]

Purpose

To terminate a user-defined transaction or make changes to the database permanent.

Usage

Anywhere.

Authorization

None.

Side effects

None.

Description

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 COMMIT statement decreases the nesting level of transactions by one. When transactions are nested, only the outermost COMMIT makes the changes to the database permanent.

For a discussion of transaction nesting in SQL Server and SQL Anywhere, see "Transact-SQL BEGIN TRANSACTION statement".

Savepoints and the ROLLBACK statement are discussed in the chapter "Watcom-SQL Language Reference".


Transact-SQL CREATE DEFAULT and CREATE RULE statements
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Transact-SQL statement reference

Transact-SQL CREATE DEFAULT and CREATE RULE statements

SQL Anywhere does not support the Transact-SQL CREATE DEFAULT statement or CREATE RULE statement. The Watcom-SQL CREATE DATATYPE statement allows a default and a rule (called a CHECK condition) to be incorporated into the definition of a user-defined data type, and so provides similar functionality to the Transact-SQL CREATE DEFAULT and CREATE RULE statements.

In SQL Server, the CREATE DEFAULT statement creates a named default which can be used as a default value for columns by binding the default to a particular column or which can be used as a default value for all columns of a user-defined data type by binding the default to the data type. A default is bound to a data type or column 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 which can be used as a rule for all columns of a user-defined data type 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 SQL Anywhere, a user-defined data type can have a default value and a CHECK condition associated with it, which are applied to all columns defined on that data type. The user-defined data type is created using the CREATE DATATYPE statement.

Default values and rules, or CHECK conditions, can be defined for individual columns using the CREATE TABLE statement or the ALTER TABLE statement. For a description of the SQL Anywhere syntax for these statements, see "Watcom-SQL Statements".


Transact-SQL CREATE INDEX statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Transact-SQL statement reference

Transact-SQL CREATE INDEX statement

The supported CREATE INDEX statement syntax is described in "CREATE INDEX statement".

SQL Server indexes can be either clustered or nonclustered. A clustered index almost always retrieves data faster than a nonclustered index. Only one clustered index is permitted per table.

SQL Anywhere does not support clustered indexes. The CLUSTERED and NONCLUSTERED keywords are allowed by SQL Anywhere, but no action is taken.

SQL Anywhere also 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 SQL Server and in SQL Anywhere. The ON segment-name clause is supported in SQL Anywhere, but segment-name refers to a SQL Anywhere dbspace.

Index names must be unique on a given table for both SQL Anywhere and SQL Server.


Transact-SQL CREATE MESSAGE statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Transact-SQL statement reference

Transact-SQL CREATE MESSAGE statement

Syntax

CREATE MESSAGE message-num

... AS 'message-text''

Purpose

To add a user-defined message to the sysusermessages system table for use by print and raiserror calls.

Usage

Anywhere.

Authorization

Resource authority

Side effects

Automatic commit.

 Description

The CREATE MESSAGE statement does not exist in SQL Server. It is an provided in SQL Anywhere as an alternative to the sp_addmessage system procedure.

The replaceable text in the syntax is as follows:

♦	message_num   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 to print out. 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 (!). The integer represents the argument number in the string in the argument list. "%1!" is the first argument in the original version, "%2!" is the second argument, and so on.

The language argument for sp_addmessage is not currently supported.


Transact-SQL CREATE SCHEMA statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Transact-SQL statement reference

Transact-SQL CREATE SCHEMA statement

SQL 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.

The CREATE SCHEMA statement supported in SQL Anywhere is described in "CREATE SCHEMA statement".


Transact-SQL CREATE TABLE statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Transact-SQL statement reference

Transact-SQL CREATE TABLE statement

SQL Anywhere does not support named constraints or named defaults, but does support user-defined data types 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.

You can create a temporary table by preceding the table name in a CREATE TABLE statement with a pound sign (#). These temporary tables are SQL Anywhere declared temporary tables, and are available only in the current connection. For information about declared temporary tables in SQL Anywhere, see "DECLARE TEMPORARY TABLE statement".

By default, columns in SQL Server default to NOT NULL, whereas in SQL Anywhere the default setting is NULL, to allow NULL values. This setting can be controlled using the allow_nulls_by_default option. For information on this option, see "Setting options for Transact-SQL compatibility". You should explicitly specify NULL or NOT NULL to make your data definition statements transferable.

Physical placement of a table is carried out differently in SQL Server and in SQL Anywhere. The ON segment-name clause is supported in SQL Anywhere, but segment-name refers to a SQL Anywhere dbspace.

  For information about the CREATE TABLE statement supported in SQL Anywhere is described in "CREATE TABLE statement".


Transact-SQL DATABASE statements
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Transact-SQL statement reference

Transact-SQL DATABASE statements

The Transact-SQL statements CREATE DATABASE, DROP DATABASE, DUMP DATABASE, and LOAD DATABASE are not supported in SQL Anywhere.

SQL Server and SQL Anywhere have different models of creating and dropping databases, reflecting the different uses for the two products.

In SQL Server, users connect to a single server, and can access the different databases running on that server. From the server, the CREATE DATABASE statement is used to create a new database, and DROP DATABASE is used to delete a database; DUMP DATABASE and DUMP TRANSACTION are used to back up a database (with its transaction log) and a transaction log only. The LOAD DATABASE and LOAD TRANSACTION statements load a backup copy of a database or transaction log.

In SQL Anywhere, users connect to a single database running on an engine or server. The SQL Anywhere engine or server can load and unload databases dynamically.

♦	To create a SQL Anywhere database, you use the initialization utility. For information on this utility, see "The Initialization utility".

♦	To erase a SQL Anywhere database, you use the erase utility. For information on this utility, see "The Erase utility".

♦	To back up a SQL Anywhere database, you use the backup utility. For information on this utility, see "The Backup utility". Transaction logs are applied to the database using database engine command-line switches.


Transact-SQL DELETE statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Transact-SQL statement reference

Transact-SQL DELETE statement

Subject to the expressions being compatible, the syntax of the DELETE statement is compatible between SQL Server and SQL Anywhere.


Transact-SQL DISK statements
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Transact-SQL statement reference

Transact-SQL DISK statements

SQL Anywhere and SQL Server use different models for managing devices and disk space, reflecting the different uses for the two products. While SQL Server sets out a comprehensive resource management scheme using a variety of Transact-SQL statements, SQL Anywhere is designed to be able to manage its own resources automatically.

For information on SQL Anywhere disk management, see "Working with databases", as well as the following statements in "Watcom-SQL Stat ements":

♦	ALTER DBSPACE statement

♦	ALTER TABLE statement

♦	CREATE DBSPACE statement

♦	CREATE INDEX statement

♦	CREATE TABLE statement

SQL Anywhere does not support Transact-SQL DISK statements, such as DISK INIT, DISK MIRROR, DISK REFIT, DISK REINIT, DISK REMIRROR, and DISK UNMIRROR.


Transact-SQL GRANT and REVOKE statements
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Transact-SQL statement reference

Transact-SQL GRANT and REVOKE statements

In SQL Server, users are created on a server-wide basis. In SQL Anywhere, users are created for individual databases. ]

For an overview of users and groups in SQL Server and SQL Anywhere, see "Users and groups in SQL Anywhere and SQL Server". SQL Anywhere provides system procedures that allow SQL Server-like management of users and groups, which are listed in that section and in "SQL Server system procedures"

Database object permissions

The SQL Server and SQL Anywhere GRANT and REVOKE statements for granting permissions on individual database objects are very similar. Both DBMS's allow SELECT, INSERT, DELETE, UPDATE, and REFERENCES permissions on database tables and views, and UPDATE permissions on selected columns of database tables. Both DBMS's allow EXECUTE permissions to be granted on stored procedures.

For example, the following statement is valid in both SQL Server and SQL 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.

The WITH GRANT OPTION clause, allowing the recipient of permission to grant them in turn, is supported in both SQL Anywhere and SQL Server, although SQL Anywhere does not permit WITH GRANT OPTION to be used on a GRANT EXECUTE statement.

Database-wide permissions

SQL Server and SQL Anywhere use different models for database-wide user permissions. These are discussed in "Users and groups in SQL Anywhere and SQL Server". SQL Anywhere employs DBA permissions to allow a user full authority within a database. This permission is enjoyed by the System Administrator in SQL Server, for all databases on a server. However, DBA authority on a SQL Anywhere database is different from the permissions of a SQL Server Database Owner, who must use the SQL Server setuser statement to gain permissions on objects owned by other users.

SQL Anywhere employs RESOURCE permissions to allow a user the right to create objects in a database. A closely corresponding SQL Server permission is GRANT ALL used by a Database Owner.


Transact-SQL INSERT statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Transact-SQL statement reference

Transact-SQL INSERT statement

Subject to the expressions being compatible, the syntax of the INSERT statement is compatible between SQL Server and SQL Anywhere. You should ensure that expressions being inserted or updated are compatible.


Transact-SQL joins
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Transact-SQL statement reference

Transact-SQL joins

In Transact-SQL, joins are specified 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 listed in the section "Compatibility of operators", or may be either of the two outer-join operators.

The Transact-SQL outer-join operators are supported in SQL Anywhere as an alternative to the native SQL/92 syntax.

For joins other than outer joins, SQL Anywhere provides a SQL/92 syntax also, in which the joins are placed in the FROM clause rather than the WHERE clause. For information about joins in SQL Anywhere and in SQL/92, see "FROM clause". Specifying the join in the WHERE clause is also accepted. All joins other than outer joins can be specified in the WHERE clause so that they are compatible with both SQL Anywhere and SQL Server.

There is some ambiguity in the meaning of the outer join operators in some situations where more than two tables are queried. For multi-table outer joins, you should confirm that the results of the query are identical in SQL Server and SQL Anywhere.


Transact-SQL READTEXT statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Transact-SQL statement reference

Transact-SQL READTEXT statement

Syntax

READTEXT table-name.column-name

...   text-pointer offset size [HOLDLOCK]

Purpose

Reads text and image values, starting from a specified offset and reading a specified number of bytes.

Usage

Anywhere.

Authorization

None.

Side effects

None.

Description

SQL Server supports the following clause, which is not supported by SQL Anywhere:

USING { BYTES | CHARS | CHARACTERS }

These options are identical for all single-byte character sets. SQL Anywhere uses bytes only, which is the SQL Server default setting.


Transact-SQL ROLLBACK statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Transact-SQL statement reference

Transact-SQL ROLLBACK statement

The Transact-SQL ROLLBACK TRANSACTION syntax is supported.

For a discussion of Transact-SQL transaction management in SQL Anywhere, see "Transact-SQL BEGIN TRANSACTION statement".


Transact-SQL SELECT statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Transact-SQL statement reference

Transact-SQL SELECT statement

There are two criteria for writing a query that runs on both SQL Anywhere and SQL Server databases:

♦	Ensure that the data types, expressions, and search conditions in the query are compatible.

♦	Ensure that the syntax of the SELECT statement itself is compatible.

This section is concerned with compatible SELECT statement syntax, and assumes compatible data types, expressions, and search conditions. The examples assume a quoted_identifier setting of OFF: the default SQL Server setting, but not the default SQL Anywhere setting.

The following subset of the Transact-SQL SELECT statement is supported in SQL Anywhere.

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 [ ASC | DESC ], ... ]   |

   | [ ORDER BY integer [ ASC | DESC ], ... ]   |

Parameters

select-list:

   { table-name | alias-name = expression }...

table-spec:

   [ owner . ]table-name

...   [ [ AS ] correlation-name ]

...   [ ( INDEX index_name [ PREFETCH size  ][ LRU | MRU ] )]

alias-name:

   identifier | 'string' | "string"

The following keywords and clauses of the Transact-SQL SELECT statement syntax are not supported by SQL Anywhere:

♦	The SHARED keyword.

♦	The COMPUTE clause.

♦	The FOR BROWSE clause.

♦	The 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.

♦	SQL Anywhere does not support the Transact-SQL extension to the GROUP BY clause allowing references to columns and expressions not used for creating groups. In SQL Server, 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 SQL 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 transaction isolation level 3 option of the set command implicitly 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 SQL Anywhere, but has no effect.

♦	Transact-SQL uses the SELECT statement to assign values to local variables:

SELECT @localvar = 42

The corresponding statement in the Watcom-SQL dialect is the SET statement:

SET localvar = 42

However, the Transact-SQL SELECT to assign values to variables is supported inside batches.

♦	The following clauses of the Watcom-SQL SELECT statement syntax are not supported by SQL Server:

♦	INTO host-variable-list

♦	INTO variable-list.

♦	Parenthesized queries.

♦	A major difference between Watcom-SQL and Transact-SQL SELECT statements is in the way that joins are specified for multi-table queries.

  For information on SQL Anywhere support for Transact-SQL joins, see "Transact-SQL joins".


Transact-SQL SET statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Transact-SQL statement reference

Transact-SQL SET statement

In SQL Server, the SET statement sets database options for the duration of a user's connection. In SQL Anywhere this task is carried out by the SET TEMPORARY OPTION statement, while SET is used to assign values to variables. The following statements show the difference in the syntaxes for setting options:

♦	Set the isolation level to 3, in SQL Server:

SET TRANSACTION ISOLATION LEVEL 3

♦	Set the isolation level to 3, in SQL Anywhere:

SET OPTION PUBLIC.ISOLATION_LEVEL = 3

The following two statements show the difference in the syntaxes for setting the values of variables:

♦	Set a variable named @var_name to a value of 3, in SQL Server:

SELECT @var_name = 3

♦	Set a variable named var_name to a value of 3, in SQL Anywhere:

SET var_name = 3

SQL Anywhere provides support for the Transact-SQL SET statement for a set of options that are particularly useful for compatibility. The following options can be set using the Transact-SQL SET statement in SQL Anywhere as well as in SQL Server:

♦	SET ANSINULL { ON | OFF }   The default behavior for comparing values to NULL in SQL Anywhere and SQL Server is different. Setting ANSINULL to OFF provides Transact-SQL compatible comparisons with NULL

♦	SET ANSI_PERMISSIONS { ON | OFF }   The default behavior in SQL Anywhere and SQL Server 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 SQL Anywhere and SQL Server for closing cursors at the end of a transaction is different. Setting CLOSE_ON_ENDTRANS to OFF provides Transact-SQL compatible behavior.

♦	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 those rows 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 SQL Anywhere, if the ROWCOUNT setting is greater than the number of rows that ISQL can display, ISQL 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.

♦	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 SQL Anywhere and SQL Server 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 TRANSACTION ISOLATION LEVEL { 0 | 1 | 2 | 3 }   Sets the locking isolation level for the current connection, as described in "Isolation levels and consistency". For SQL Server, only 1 and 3 are valid options. For SQL Anywhere, any of 0, 1, 2, or 3 is a valid option.

  For more information on these and other database options, see "SET OPTION statement".

In addition, the following SET statement is allowed by SQL Anywhere for compatibility, but has no effect:

♦	SET PREFETCH {ON | OFF}


Transact-SQL UPDATE statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Transact-SQL statement reference

Transact-SQL UPDATE statement

Subject to the expressions being compatible, the syntax of the UPDATE statement is compatible between SQL Server and SQL Anywhere. You should ensure that expressions being inserted or updated are compatible.


Transact-SQL WRITETEXT statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Transact-SQL statement reference

Transact-SQL WRITETEXT statement

Syntax

WRITETEXT table-name.column-name

...   text_pointer [ WITH LOG ] data

Purpose

Permits non-logged, interactive updating of an existing text or image column.

Usage

Anywhere.

Authorization

None.

Side effects

WRITETEXT does not fire triggers, and by default WRITETEXT operations are not recorded in the transaction log.

Description

Updates an existing text or image value. The update is not recorded in the transaction log unless the WITH LOG option is supplied.


Compatible system catalog information
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Compatible system catalog information

SQL Server and SQL Anywhere have different system catalogs, reflecting the different uses for the two products.

In SQL Server there is a single master database containing a set of system tables holding 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 SQL 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 SQL Server and SQL Anywhere system catalogs are different. The SQL Server 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 SQL Anywhere system tables and views are owned by the special user SYS and exist separately in each database.

To assist in preparing compatible applications, SQL Anywhere provides a set of views owned by the special user dbo, which correspond to the SQL Server system tables and views. Where architectural differences make the contents of a particular SQL Server table or view meaningless in a SQL Anywhere context, the view is empty, containing just the column names and data types.

The following tables list the SQL Server system tables and their implementation in the SQL Anywhere system catalog. The owner of all tables is dbo in each DBMS.

Tables existing in each SQL Server 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 SQL definition statement	Yes
sysconstraints	One row for each referential and 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, and 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 user (not maintained by SQL Server)	No
syslogs	Transaction log	No
sysobjects	One row for each table, view, procedure, rule, trigger default, log, and (in tempdb only) temporary object	Contains compatible data only
sysprocedures	One row for each view, rule, default, trigger, and procedure, giving 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 and user-defined datatype	Yes
sysusermessages	One row for each user-defined message	Yes (this is a SQL Anywhere system table)
sysusers	One row for each user allowed in the database	Yes
Tables existing in the SQL Server 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, and disk partition for databases	No
sysengines	One row for each engine 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
syssrvroles	One row for each server-wide role	No
sysservers	One row for each remote server	No
sysusages	One row for each disk piece allocated to a database	No
Tables existing in the SQL Server sybsecurity database

Table name	Description	Data?
sysaudits	One row for each audit record	No
sysauditoptions	One row for each global audit option	No


SQL Server system and catalog procedures
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

SQL Server system and catalog procedures

SQL Server provides system and catalog procedures to carry out many administrative functions and to obtain system information. SQL 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.

 SQL Server system procedures

 SQL Server catalog procedures


SQL Server system procedures
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

SQL Server system and catalog procedures

SQL Server system procedures

The following list describes the SQL Server system procedures provided in SQL Anywhere.

System procedure	Description
sp_addgroup group-name	Adds a group to a database
sp_addlogin userid, password[, defdb [, deflanguage [, fullname]]]	Adds a new user account to a database
sp_addmessage message-num, message_text [, language]	Adds user-defined messages 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 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 database options
sp_dropgroup group-name	Drops a group from a database
sp_droplogin userid	Drops a user from a database
sp_dropmessage message-number [, language]	Drops user-defined messages
sp_droptype typename	Drops a user-defined data type
sp_dropuser userid	Drops a user from a database
sp_getmessage message-num, @msg-var output [, language]	Retrieves stored message strings from SYSMESSAGES and 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


SQL Server catalog procedures
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

SQL Server system and catalog procedures

SQL Server catalog procedures

SQL Anywhere implements all catalog procedures with the exception of the sp_column_privileges procedure. The implemented catalog procedures are described in the following table.

The following list describes the SQL Server catalog procedures provided in SQL Anywhere.

Catalog procedure	Description
sp_column_privileges	Unsupported
sp_columns table-name [, table-owner ] [, table-qualifier] [, column-name]	Returns the data types of the specified column
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 for a single table
sp_special_columns table_name [, table-owner] [, table-qualifier] [, col-type]	Returns the optimal set of columns that uniquely identify a row in a 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_tables table-name [, table-owner] [, table-qualifier] [, table-type]	Returns a list of objects that can appear in a FROM clause


Implicit data type conversion
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Implicit data type conversion

Both SQL Anywhere and SQL Server carry out implicit data type conversions among some of the data types. Implicit data type conversions are conversions carried out as required by the context, and without any explicit data type conversion function being called. For example, if you compare a CHAR expression and a DATETIME expression, or a SMALLINT expression and an INT expression, or CHAR expressions of different lengths, both SQL Anywhere and SQL Server automatically convert one data type to another in order to carry out the comparison.

This section documents the differences between SQL Anywhere and SQL Server implicit data type conversions.

 Differences in string to datetime conversions


Differences in string to datetime conversions
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 29. Using Transact-SQL with SQL Anywhere

Implicit data type conversion

Differences in string to datetime conversions

There are differences in behavior between SQL Anywhere and SQL Server 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, SQL Server uses a default date of January 1, 1900, SQL Anywhere uses the current date.

If the milliseconds portion of a time is less than 3 digits, SQL Server 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. SQL Anywhere interprets the value the same way, regardless of the separator.

For example, SQL Server would convert the values below as shown.

12:34:56.7 to 12:34:56.700

12.34.56.78 to 12:34:56.780

12:34:56.789 to 12:34:56.789

12:34:56:7 to 12:34:56.007

12.34.56:78 to 12:34:56.078

12:34:56:789 to 12:34:56.789

SQL Anywhere converts the milliseconds value in the manner that SQL Server does for values preceded by a period, in both cases:

12:34:56.7 to 12:34:56.700

12.34.56.78 to 12:34:56.780

12:34:56.789 to 12:34:56.789

12:34:56:7 to 12:34:56.700

12.34.56:78 to 12:34:56.780

12:34:56:789 to 12:34:56.789


Transact-SQL Procedure Language
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

About this chapter

The chapter describes the SQL Anywhere support for writing procedures, triggers, and batches that are portable between SQL Server and SQL Anywhere. Procedures, triggers, and batches all include sets of SQL statements.

The audience for this chapter includes those moving applications from SQL Server to SQL Anywhere, and those developing applications on SQL Anywhere that will also be used on SQL Server.

Before you begin

If you are developing applications for SQL Anywhere only, see the information in the chapter "Using Procedures, Triggers, and Batches" and in the Reference section: you do not need to read this chapter.

 Transact-SQL procedure language overview

 Automatic translation of SQL statements

 Transact-SQL stored procedure overview

 Transact-SQL trigger overview

 Transact-SQL batch overview

 Supported Transact-SQL procedure language statements

 Returning result sets from Transact-SQL procedures

 Variable and cursor declarations

 Error handling in Transact-SQL procedures


Transact-SQL procedure language overview
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

Transact-SQL procedure language overview

The previous chapter described SQL Anywhere support for individual SQL statements. This chapter describes the SQL Anywhere support for sets of SQL statements, whether they appear as stored procedures, triggers, or batches. Also discussed in this chapter are individual statements that are typically found within stored procedures, such as variable assignment statements, as well as control-of-flow statements such as IF and WHILE, and compound statements (bracketed by BEGIN and END). Collectively, these aspects of SQL are called the procedure language.

This chapter describes how the two dialects of SQL coexist in SQL Anywhere, and describes the SQL Anywhere functions for automatic translation of Transact-SQL procedures. The chapter also provides reference for the individual statements that make up the Transact-SQL procedure language.

 Mixing Transact-SQL and Watcom-SQL dialects


Mixing Transact-SQL and Watcom-SQL dialects
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

Transact-SQL procedure language overview

Mixing Transact-SQL and Watcom-SQL dialects

SQL Anywhere supports two SQL dialects: the native Watcom-SQL and Sybase Transact-SQL. There is a large overlap between the two dialects: SELECT * FROM employee is a SQL statement that is part of both Watcom-SQL and Transact-SQL.

Transact-SQL only

There are SQL statements supported by SQL Anywhere that are part of one dialect, but not the other. For example: the following are part of the Transact-SQL dialect only:

♦	The Transact-SQL control statements IF and WHILE.

♦	The Transact-SQL EXECUTE statement.

♦	The Transact-SQL CREATE PROCEDURE and CREATE TRIGGER statements.

♦	The Transact-SQL BEGIN TRANSACTION statement.

♦	SQL Statements not separated by semicolons are part of a Transact-SQL procedure or batch.

Watcom-SQL only

The following statements are part of the Watcom-SQL dialect only:

♦	The Watcom-SQL control statements CASE, IF, LOOP, FOR, and WHILE.

♦	The Watcom-SQL CALL statement.

♦	The Watcom-SQL CREATE PROCEDURE, CREATE FUNCTION, and CREATE TRIGGER statements.

♦	SQL Statements separated by semicolons are part of a Watcom-SQL procedure or batch.

Notes

The two dialects cannot be mixed within a procedure, trigger, or batch. That is:

♦	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 Watcom-SQL-only statements together with statements that are part of both dialects in a batch, procedure, or trigger.

♦	You cannot include Transact-SQL-only statements together with Watcom-SQL-only statements in a batch, procedure, or trigger: a syntax error results.


Automatic translation of SQL statements
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

Automatic translation of SQL statements

In addition to supporting Transact-SQL alternative syntax, SQL Anywhere provides aids for translating statements between the Watcom-SQL and Transact-SQL dialects. The following functions return information about SQL statements and enable automatic translation of SQL statements:

♦	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, for example, using a select statement from ISQL. For example, the following statement:

select SqlDialect('select * from employee')

returns the value WatcomSQL.

 Using Sybase Central to translate stored procedures


Using Sybase Central to translate stored procedures
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

Automatic translation of SQL statements

Using Sybase Central to translate stored procedures

The Sybase Central database management tool has facilities for creating, viewing, and altering procedures and triggers.

  For information on connecting to a database using Sybase Central, and displaying database objects, see the chapter "Managing Databases with Sybase Central" or the Sybase Central online help.

 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	Double-click the Procedures folder for the database to list the stored procedures in the database.

3	Using the right mouse button, click the procedure you wish to translate, and choose the dialect you wish to translate it to from the popup menu: either Watcom-SQL or Transact-SQL.

The procedure is displayed in the selected dialect. If the selected dialect is not the one in which the procedure is stored, it is translated to that dialect by the database engine. Any untranslated lines are displayed as comments.

4	Rewrite any untranslated lines as needed, and click the Execute Script button to save the translated version to the database. You can also export the text to a file for editing outside Sybase Central.


Transact-SQL stored procedure overview
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

Transact-SQL stored procedure overview

The Watcom-SQL stored procedure language is based on the ISO/ANSI draft standard, which differs from the Transact-SQL dialect in many ways. Many of the concepts and features are similar, but the syntax is different. SQL Anywhere support for Transact-SQL takes advantage of the similar concepts by providing automatic translation between the Watcom-SQL and Transact-SQL dialects. However, a procedure must be written in one of the two dialects exclusively, not in a mixture.

SQL Anywhere support for Transact-SQL stored procedures

SQL Anywhere support for the following Transact-SQL stored procedure elements is discussed in this chapter:

♦	Passing parameters

♦	Returning result sets

♦	Returning status information

♦	Providing default values for parameters

♦	Control statements

♦	Error handling


Transact-SQL trigger overview
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

Transact-SQL trigger overview

Trigger compatibility requires compatibility of trigger features and of trigger syntax. This section provides an overview of the feature compatibility of Transact-SQL and SQL Anywhere triggers.

SQL Server triggers are executed after the triggering statement has completed: they are statement level, after triggers. SQL 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 has been executed).

Row-level triggers are not discussed here, as they are not part of the Transact-SQL compatibility features. For information on row-level triggers in SQL Anywhere, see the chapter "Using Procedures, Triggers, and Batches".

Description of unsupported or different Transact-SQL triggers

The following list describes some features of Transact-SQL triggers that are either not supported or are different in SQL Anywhere:

♦	Triggers firing other triggers   Suppose a trigger carries out an action that would, if carried out directly by a user, fire another trigger. SQL Anywhere and SQL Server have slightly different behavior for this case. The default SQL Server behavior is for triggers to fire other triggers up to a configurable nesting level, which has the default value of 16. The nesting level can be controlled by the SQL Server option nested triggers. In SQL Anywhere, triggers fire other triggers without limit unless memory is exhausted.

♦	Triggers firing themselves   Suppose a trigger carries out an action that would, if carried out directly by a user, fire the same trigger. SQL Anywhere and SQL Server have different behavior for this case. The default SQL Server behavior is that a trigger does not call itself recursively, but you can turn on the self_recursion option to allow triggers to call themselves recursively. The default SQL Anywhere behavior for Watcom-SQL dialect triggers is for triggers to fire themselves recursively. The default SQL Anywhere behavior for Transact-SQL dialect triggers is for triggers not to fire themselves recursively. This behavior is configurable using the Transact-SQL SET SELF_RECURSION { ON | OFF} statement; see "Transact-SQL SET statement".

♦	ROLLBACK statement in triggers   SQL Server permits the ROLLBACK TRANSACTION statement within triggers, which rolls back the entire transaction of which the trigger is a part. SQL Anywhere does not permit ROLLBACK (or ROLLBACK TRANSACTION) statements in triggers. A triggering action and its trigger together form an atomic statement, and SQL Anywhere does not permit ROLLBACKs within atomic statements.

♦	ROLLBACK TRIGGER statement   The ROLLBACK TRIGGER statement is not supported by SQL Anywhere.


Transact-SQL batch overview
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

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. A SQL Anywhere command file serves a similar function to a batch file, and the ISQL utility in SQL Anywhere and in SQL Server provide similar capabilities for executing batches interactively.

The control statements used in procedures can also be used in batches. SQL 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.

Parameters in command files are supported in SQL Anywhere, but not by SQL Server.


Supported Transact-SQL procedure language statements
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

Supported Transact-SQL procedure language statements

This section lists the supported Transact-SQL procedure language statements:

 Transact-SQL BEGIN ... END statement

 Transact-SQL CREATE PROCEDURE statement

 Transact-SQL CREATE TRIGGER statement

 Transact-SQL EXECUTE statement

 Transact-SQL GOTO statement

 Transact-SQL IF statement

 Transact-SQL PRINT statement

 Transact-SQL RAISERROR statement

 The Transact-SQL RETURN statement

 Transact-SQL WHILE statement


Transact-SQL BEGIN ... END statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

Supported Transact-SQL procedure language statements

Transact-SQL BEGIN ... END statement

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 performance of a single SQL statement, can affect the performance of the whole group.

In Watcom-SQL, the BEGIN and END keywords are not needed for control statements, as the Watcom-SQL control statements affect blocks of statements, rather than a single statement. The BEGIN and END keywords are required in Watcom-SQL to enclose the body of a stored procedure or trigger. The Watcom-SQL compound statement supports the ATOMIC keyword, that is not part of the Transact-SQL dialect.

In Watcom-SQL, DECLARE statements must always immediately follow a BEGIN keyword, and the cursor or variable declared exists for the duration of the compound statement. Variable declarations in Transact-SQL have different behavior: for more information, see "Variable and cursor declarations".


Transact-SQL CREATE PROCEDURE statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

Supported Transact-SQL procedure language statements

Transact-SQL CREATE PROCEDURE statement

The following subset of the Transact-SQL CREATE PROCEDURE statement is supported by SQL Anywhere.

Syntax

CREATE PROCEDURE [owner.]procedure_name

...   [ [ ( ] @parameter_name data-type

...   [ = default ] [ output ], ... [ ) ] ]

...   [ WITH RECOMPILE ]

...   AS

...   compound statement

Notes

♦	If the Transact-SQL WITH RECOMPILE optional clause is supplied, it is ignored. SQL 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.

 Comparison of Transact-SQL and Watcom-SQL CREATE PROCEDURE statements


Comparison of Transact-SQL and Watcom-SQL CREATE PROCEDURE statements
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

Supported Transact-SQL procedure language statements

Transact-SQL CREATE PROCEDURE statement

Comparison of Transact-SQL and Watcom-SQL CREATE PROCEDURE statements

The following differences between Transact-SQL and Watcom-SQL statements 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 specified as IN, OUT, or INOUT, while 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 SQL 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

  For more information, see "Returning result sets from Transact-SQL procedures".

♦	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.


Transact-SQL CREATE TRIGGER statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

Supported Transact-SQL procedure language statements

Transact-SQL CREATE TRIGGER statement

The following Transact-SQL CREATE TRIGGER syntax is supported in SQL Anywhere.

Syntax

1. CREATE TRIGGER [owner.]trigger_name

   ...   ON [owner.]table_name

   ...   FOR { INSERT , UPDATE , DELETE }

   ...   AS

   ...   statement-list

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

Notes

♦	The rows deleted or inserted are held in two declared temporary tables given the default names deleted, and inserted, as in SQL Server.

♦	In SQL Server, trigger names must be unique in the database. In SQL Anywhere, trigger names must be unique for a given owner. For compatible databases, you should make trigger names unique in the database.

♦	Transact-SQL triggers are executed after the triggering statement.


Transact-SQL EXECUTE statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

Supported Transact-SQL procedure language statements

Transact-SQL EXECUTE statement

The Transact-SQL EXECUTE statement is supported to execute stored procedures, as an alternative to the Watcom-SQL CALL statement.

The EXECUTE syntax is as follows

Syntax

EXECUTE [ @return_status = ] [creator.]procedure_name

...    | [@parameter-name = ] expression,    |

    | [@parameter-name =] @variable [output]   |, ...

Purpose

To invoke a procedure, as an alternative to the Watcom-SQL CALL statement.

Usage

Anywhere

Authorization

Must be the owner of the procedure, have EXECUTE permission for the procedure, or have DBA authority.

Side effects

None.

Description

The EXECUTE statement 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.


Transact-SQL GOTO statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

Supported Transact-SQL procedure language statements

Transact-SQL GOTO statement

Syntax

label:

GOTO label

Purpose

To branch to a labeled statement.

Usage

Procedures, triggers, and batches only.

Authorization

None.

Side effects

None.

Description

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.


Transact-SQL IF statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

Supported Transact-SQL procedure language statements

Transact-SQL IF statement

Syntax

 IF expression

...     statement

...    [ ELSE

...    [ IF expression ]

...     statement ]

Purpose

To provide conditional execution of a SQL statement, as an alternative to the Watcom-SQL IF statement.

Usage

Procedures, triggers, and batches only.

Authorization

None.

Side effects

None.

Description

The Transact-SQL IF conditional and the ELSE conditional each control the performance of only a single SQL statement or compound statement (between the keywords BEGIN and END).

Notes

♦	There is no THEN in the Transact-SQL IF statement.

♦	Transact-SQL has no ELSEIF or END IF keywords.

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


Transact-SQL PRINT statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

Supported Transact-SQL procedure language statements

Transact-SQL PRINT statement

Syntax

PRINT format-string [, arg-list]

Purpose

To display a message on the message window of the database engine or server.

Usage

Procedures, triggers, and batches.

Authorization

Must be connected to the database.

Side effects

None.

 Description

The PRINT statement displays an expression on the message window of the database engine or server. In SQL Server the message is displayed on the client 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.


Transact-SQL RAISERROR statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

Supported Transact-SQL procedure language statements

Transact-SQL RAISERROR statement

Syntax

RAISERROR error-number [ format-string ] [, arg-list]

Purpose

To signal an error, and display a message on the message window of the database engine or server.

Usage

Anywhere.

Authorization

Must be connected to the database.

Side effects

None.

Description

The RAISERROR statement allows user-defined errors to be signaled, and displays a message on the engine or server message window. In SQL Server, the message is displayed on the client window.

The error-number is a five-digit integer greater than 17000. If format-string is not supplied or is empty, the error number is used to locate an error message in the system tables. SQL Server obtains messages 17000-19999 from the SYSMESSAGES table. In SQL 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. The error number is stored in the global variable @@error.

The extended values supported by the SQL Server RAISERROR statement are not supported in SQL 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.


The Transact-SQL RETURN statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

Supported Transact-SQL procedure language statements

The Transact-SQL RETURN statement

Syntax

RETURN [ integer-expression ]

Purpose

To exit a procedure, returning an integer status value to the calling environment.

Usage

Procedures and triggers only.

Authorization

None.

Side effects

None.

Description

The RETURN statement exits a procedure. Statements following the RETURN statement are not executed. If an integer expression is supplied, that is returned to the calling statement as the return value of the procedure. If no integer expression is supplied, a built-in integer status value between 0 and -15 is returned to the calling environment, describing the success of the procedure.

The return value can be assigned to a local variable as in the following batch:

DECLARE @status INT

EXECUTE @status = sample_proc

PRINT 'status = %1!', @status

  For a description of procedure return values, see "Error handling in Transact-SQL procedures".


Transact-SQL WHILE statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

Supported Transact-SQL procedure language statements

Transact-SQL WHILE statement

Syntax

 WHILE expression

...     statement

Purpose

To provide repeated execution of a statement or compound statement.

Usage

Procedures and triggers only.

Authorization

None.

Side effects

None.

Description

The WHILE conditional affects the performance 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.


Returning result sets from Transact-SQL procedures
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

Returning result sets from Transact-SQL procedures

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.

Example of Transact-SQL procedure

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

Example of Watcom-SQL procedure

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

Notes

♦	Multiple result sets with a different number of columns or incompatible data types cannot be returned from procedures in SQL Anywhere.

♦	When a RESULT clause is not specified (as is the case with Transact-SQL procedures), SQL Anywhere determines the result set from the first SELECT statement in the procedure. The first SELECT statement is identified without regard for IF statements or other control statements: you cannot have a procedure return one result set under one set of conditions an incompatible result set under other conditions.

♦	SQL Anywhere does not support the case where a Transact-SQL procedure creates a temporary table and issues a SELECT to return the contents of that table as the result set. In this case, you can convert the procedure to the Watcom-SQL dialect and directly specify the result set. SQL Anywhere also does not support the case where a Transact-SQL procedure creates a local variable and returns its value by including it in a SELECT list. The data type of the variable must be specified in the SELECT statement using a CONVERT or CAST function.


Variable and cursor declarations
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

Variable and cursor declarations

The syntax of the DECLARE CURSOR and DECLARE statements is very similar in Transact-SQL and Watcom-SQL. This section describes the Transact-SQL DECLARE CURSOR statement.

 Transact-SQL DECLARE CURSOR statement

 Transact-SQL DECLARE statement


Transact-SQL DECLARE CURSOR statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

Variable and cursor declarations

Transact-SQL DECLARE CURSOR statement

The following subset of the Transact-SQL DECLARE CURSOR statement is supported by SQL Anywhere.

Syntax

DECLARE cursor-name CURSOR FOR select_statement

...   [ FOR { READ ONLY | UPDATE } ]

SQL Server supports cursors opened for update of a list of columns from the tables specified in the select_statement. This is not supported in SQL Anywhere.

Notes

♦	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 SQL Server,when a cursor is declared in a procedure, trigger, or batch, it exists for the duration of the procedure, trigger, or batch. In SQL 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).

♦	Watcom-SQL also supports the CREATE VARIABLE statement, which creates a variable that exists for the duration of a connection or until it is explicitly dropped using the DROP VARIABLE statement.

♦	You should be careful about using the DECLARE statement in ISQL to declare local variables. If you submit a set of statements separated by semicolons, ISQL parses them and sends them individually to the engine rather than as a batch. Each statement becomes its own "batch", and the declared variable is not accessible beyond the end of its own batch: that is, it is not accessible anywhere. You can prevent ISQL from breaking up the statements by enclosing them in a BEGIN and an END. Alternatively, you could omit the semicolons, and the batch will be sent as a Transact-SQL batch to the engine.


Transact-SQL DECLARE statement
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

Variable and cursor declarations

Transact-SQL DECLARE statement

The syntax of the Transact-SQL DECLARE statement for a single variable is the same as that for Watcom-SQL, except that the variable name must be preceded by an @ sign in Transact-SQL, while this is optional in the Watcom-SQL dialect.

Syntax

DECLARE @variable_name data-type

SQL Server allows several variables to be declared in a single statement. Only a single variable can be declared in one statement in SQL Anywhere.

Notes

♦	In the Watcom-SQL dialect, a DECLARE statement in a procedure, trigger, or batch must immediately follow the BEGIN keyword. In the Transact-SQL dialect, there is no such restriction.

♦	In SQL Server,when a variable is declared in a procedure or trigger, it exists for the duration of the procedure or trigger. In SQL 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).

 Assigning values to variables in Transact-SQL


Assigning values to variables in Transact-SQL
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

Variable and cursor declarations

Transact-SQL DECLARE statement

Assigning values to variables in Transact-SQL

Watcom-SQL uses the SET statement to assign values to variables in a procedure. In Transact-SQL, values are assigned using the SELECT statement with an empty table-list. 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 ;

EXECUTE multiply 5, 6, @product OUTPUT;

The variable @product has a value of 30 after the procedure is executed.

  For more information on using the SELECT statement to assign variables, see "Transact-SQL SELECT statement". For more information on using the SET statement to assign variables, see "SET statement".


Error handling in Transact-SQL procedures
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

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 an error is encountered, returning a SQLSTATE and SQLCODE value to the calling environment. Explicit error handling can be built in to Watcom-SQL stored procedures using the EXCEPTION statement, or the procedure can be instructed by the ON EXCEPTION RESUME statement to continue execution at the next statement when an error is encountered.

When an error is encountered in a Transact-SQL dialect procedure, 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 otherwise 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 integers other than these, with their own user-defined meanings.

 Using the RAISERROR statement in procedures

 Transact-SQL-like error handling in the Watcom-SQL dialect


Using the RAISERROR statement in procedures
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

Error handling in Transact-SQL procedures

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 Watcom-SQL SIGNAL statement. For a description of the RAISERROR statement, see "Transact-SQL RAISERROR statement".

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.


Transact-SQL-like error handling in the Watcom-SQL dialect
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 30. Transact-SQL Procedure Language

Error handling in Transact-SQL procedures

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

Explicit exception handling code is not executed if an ON EXCEPTION RESUME clause is present.


Using the Open Server Gateway
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 31. Using the Open Server Gateway

About this chapter

This chapter describes the Open Server Gateway for SQL Anywhere: an application that enables SQL Server client applications to work with SQL Anywhere.

The chapter describes the uses of the Open Server Gateway, outlines its architecture, and describes how to configure and manage it. The chapter also provides a description of incompatibilities with SQL Server.

The chapter is intended for developers implementing client applications that will use the Open Server Gateway to manipulate SQL Anywhere databases, and for users of Sybase Open Client applications who wish to use them with SQL Anywhere also.

In order to run the Open Server Gateway, you must have Sybase Open Client and Open Server kits.

 Open Server Gateway overview

 Open Server Gateway architecture

 Data type mappings

 Setting up the Open Server Gateway

 Events handled by Open Server Gateway

 Using SQL Anywhere with OmniCONNECT


Open Server Gateway overview
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 31. Using the Open Server Gateway

Open Server Gateway overview

SQL Server client applications communicate with SQL Server using the Open Client libraries provided by Sybase. The client applications can instead work with SQL Anywhere using Open Server Gateway. The purpose of Open Server Gateway is to enable client applications to communicate with both SQL Server and SQL Anywhere. The Open Server Gateway is one part of the SQL Server compatibility offered by SQL Anywhere.

Replication Server support

The Open Server Gateway is part of SQL Anywhere support for Sybase Replication Server: Replication Server connects to SQL Anywhere through the Open Server Gateway, enabling SQL Anywhere databases to act as replicate sites in Replication Server installations. Also, Sybase isql can send SQL statements to SQL Anywhere through Open Server Gateway.

For SQL Anywhere databases to act as a primary site in a Replication Server installation, you must also purchase the Replication Agent for Sybase SQL Anywhere, also called a Log Transfer Manager. This is available from Sybase as a separate product.

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 it is located. In addition, OmniCONNECT performs heterogeneous joins of data across the enterprise, enabling cross-platform table joins of targets such as DB2, Sybase SQL Server, Oracle, and VSAM.

Using the Open Server Gateway, Sybase SQL Anywhere can act as a data source for OnmiCONNECT. The archiecture of OmniCONNECT is illustrated in the figure.


Open Server Gateway architecture
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 31. Using the Open Server Gateway

Open Server Gateway architecture

The Open Server Gateway for SQL Anywhere allows database client applications built using the Sybase Open Client library to communicate with SQL Anywhere database servers.

The Open Server Gateway acts as a server application to the client application, responding to its requests. It also acts as a client application for SQL Anywhere database servers or engines, passing requests from client applications on to the SQL Anywhere server and receiving responses. An application that acts as both client and server is called a gateway application.

Event handling interface

When a client application sends a request to Open Server Gateway, it triggers an event, and the Open Server Gateway executes a routine to handle that event. Open Server Gateway functionality is described in terms of these events: the events to which it can respond, and the ways in which it responds to each event. For a description of Open Server Gateway event handling, see "Events handled by Open Server Gateway".

Open Server Gateway returns results to a client application as messages, rows of data, result parameters, or status values. A single client request can have more than one set of results.

The Open Server Gateway is designed to allow client applications to work with both SQL Server and with SQL Anywhere databases. It handles events that SQL Server client applications generate, translates them where necessary so that the SQL Anywhere server can respond to them, and passes them on to the SQL Anywhere server. On receiving results from the server, Open Server Gateway translates them where necessary into a form that the client application can understand, and passes them back.

Examples

Events include the following:

♦	SRV_LANGUAGE A client has sent a language request, such as a SQL statement.

♦	SRV_OPTION A client has sent an option command.

♦	SRV_CONNECT A Client-Library client has called ct_connect. These events are examples of standard events. For a description of supported and unsupported standard events, see "Events handled by Open Server Gateway".

 What you need to use the Open Server Gateway


What you need to use the Open Server Gateway
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 31. Using the Open Server Gateway

Open Server Gateway architecture

What you need to use the Open Server Gateway

The Open Server Gateway communicates with client applications using network libraries supplied as part of the Sybase SQL Server products. In order to run Open Server Gateway, you must elect to install the Open Server components when installing SQL Anywhere.

Ensure your database is compatible

Any Sybase SQL Anywhere database can be accessed using the Open Server Gateway. However, you should ensure that your database is created for maximum compatibility with SQL Server. For more information about making your SQL Anywhere database as compatible as possible with SQL Server, see "Configuring SQL Anywhere for Transact-SQL compatibility".

The Open Server Gateway does take some actions itself on connecting to help ensure SQL Server-compatible behavior. These actions are described in "Open Server Gateway actions on connecting".


Data type mappings
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 31. Using the Open Server Gateway

Data type mappings

The range of possible Open Client data types differs from the range of possible SQL Anywhere data types. For this reason, Open Server Gateway must map some data types between what data types are used by Open Client applications and expected in a database they connected with, and what data types are available in  SQL Anywhere.

Data types understood by Open Client applications and those available in SQL Anywhere fall into the following categories:

♦	Data types that can exist in both the Open Client and SQL Anywhere, allowing values to be exchanged without problems.

♦	Data types that can exist in both Open Client applications and SQL Anywhere but which have different ranges of possible values.

♦	Data types that can contain the same values in both Open Client applications and SQL Anywhere but are named or described differently.

♦	Open Client data types not supported by SQL Anywhere.

Specifically which data types fit into these categories has been modified with release 5.502 of SQL Anywhere. The following sections detail the use of Open Client application data types with release 5.501, and release 5.502 of SQL Anywhere.

 Problem-free Open Client data types

 Data type mappings between systems

 Data types with value range limitations

 Open Client data types with description limitations

 Incompatible Open Client data types


Problem-free Open Client data types
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 31. Using the Open Server Gateway

Data type mappings

Problem-free Open Client data types

The following table lists Open Client data types that are supported and considered problem free for use with SQL Anywhere. Use these data types to avoid any data type problems in an Open Client application connecting to a SQL Anywhere database through Open Server Gateway.

Open Client applications connecting to SQL Anywhere 5.501 and earlier releases	Open Client applications connecting to SQL Anywhere 5.502 and later releases
tinyint	tinyint
smallint	smallint
int	int
real	real
char	char
varchar	varchar
datetime	datetime
text	text
image	image
decimal	numeric*
binary	varbinary
	money
	smallmoney
* The SQL Anywhere data types numeric (20,4) and numeric (10,4) data types have a different behavior from Numeric data types of other precisions. The Open Server Gateway maps these data types to the Open Client data types Money and Smallmoney. Form more information on data type mapping from SQL Anywhere to Open Client, see "Mapping data from SQL Anywhere to Open Client".

Replication Server: use problem-free data types

Replication Server's SUBCMP (or RSSUBCMP) utility insists that data types match precisely. If you plan to use this utility between a SQL Server and a SQL Anywhere database, use only data types listed in the "SQL Anywhere 5.502 and beyond" column of the above table, "Problem-free Open Client data types".

New behavior in 5.502—The data types decimal and binary were previously considered to be problem free in release 5.501. The behavior of release 5.502 has been altered in that these data types are now considered to have description problems. Open Client applications using decimal and binary data types and connecting to SQL Anywhere through Open Server Gateway may have problems when upgrading to release 5.502.
  For more information about data types with description problems, see "Open Client data types with description limitations".

 Release 5.501 compatibility switch


Release 5.501 compatibility switch
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 31. Using the Open Server Gateway

Data type mappings

Problem-free Open Client data types

Release 5.501 compatibility switch

To obtain the Open Server Gateway data type mappings available in release 5.501 while using release 5.502, use the -c 5501 compatibility command-line switch.

  For more information on Open Server Gateway command-line switches including the -c 5501 compatibility switch, see "The Open Server Gateway"


Data type mappings between systems
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 31. Using the Open Server Gateway

Data type mappings

Data type mappings between systems

With the exception of the data types listed in "Problem-free Open Client data types", many Open Client data types are mapped by Open Server Gateway to SQL Anywhere data types which have different names or underlying structures.

Return data type may differ from original

It is possible that some values passed by Open Client to SQL Anywhere as one data type, may be converted by Open Server Gateway into a SQL Anywhere-specific data type. When it is returned or fetched by the Open Client application it may be mapped by the Open Server Gateway to yet another data type, different from the value's original data type.

For this reason, the following table illustrates the data type mapping from Open Client applications to SQL Anywhere. A second table illustrates the data type mapping from SQL Anywhere (releases 5.501 and 5.502) to Open Client applications.

All data types mappings are listed, including those for which there are no issues (for example, data types that map directly from Open Client applications to SQL Anywhere and from SQL Anywhere to Open Client applications).

 Mapping data from Open Client to SQL Anywhere

 Mapping data from SQL Anywhere to Open Client


Mapping data from Open Client to SQL Anywhere
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 31. Using the Open Server Gateway

Data type mappings

Data type mappings between systems

Mapping data from Open Client to SQL Anywhere

When a value in an Open Client application is passed to SQL Anywhere, it may be converted from an Open Client data type to a SQL Anywhere data type, depending on its original data type. The following table illustrates the mapping of data types performed by Open Server Gateway when an Open Client application passes a value to SQL Anywhere.

The mapping illustrated in the following table applies to all SQL Anywhere releases, except where noted.

Open Client Data type	SQL Anywhere data type
tinyint	tinyint
smallint	smallint
int	int
real (4 byte)	real
float (8 byte) in host variables	double
float (8 byte) in SQL statements	real
char	char
varchar	varchar
binary	binary/varbinary**
varbinary	binary/varbinary**
bit	tinyint
numeric	decimal
decimal	decimal
text	long varchar
image	long binary
datetime	timestamp
smalldatetime	timestamp
timestamp (SQL statements only)	timestamp
money	decimal (20,4)
smallmoney	decimal (10,4)
sysname (SQL statements only)	varchar(30)
long char (host variables only)*	long varchar (max. 32767 bytes)
long binary (host variables only)*	long binary (max. 32767 bytes)
ALL OTHERS	ERROR
* Applies to release 5.502 and greater of SQL Anywhere only.

** SQL Anywhere Binary data types have an underlying structure that is identical to what is commonly understood to be a Varbinary data type. For more information search the online help for "BINARY data type".


Mapping data from SQL Anywhere to Open Client
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 31. Using the Open Server Gateway

Data type mappings

Data type mappings between systems

Mapping data from SQL Anywhere to Open Client

The following table illustrates the mapping from SQL Anywhere data types to Open Client applications depending on the release of SQL Anywhere being used.

SQL Anywhere data type	Open client connecting to SQL Anywhere 5.501	Open client connecting to SQL Anywhere 5.502
tinyint	tinyint	tinyint
smallint	smallint	smallint
int	int	int
real	real (4 byte)	real (4 byte)
double	float (8 byte)	float (8 byte)
string	char	char
char	char	char
varchar	varchar	varchar
date	datetime	datetime
time	datetime	datetime
timestamp	datetime	datetime
long varchar	text	text
long binary	image	image
timestamp struct	ERROR	ERROR
variable	ERROR	ERROR
binary/varbinary	binary	varbinary
decimal*	decimal	numeric
decimal (20,4)	decimal (20,4)	money
decimal (10,4)	decimal (10,4)	smallmoney
* The data mapping of Decimal data types applies to all precisions, except Decimal (20,4) and Decimal (20,4) as noted in the last two rows of the above table.


Data types with value range limitations
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 31. Using the Open Server Gateway

Data type mappings

Data types with value range limitations

The following table lists Open Server application data types that can be mapped to SQL Anywhere data types, but with some restriction in the range of possible values.

In most of these cases, the Open Client data type is mapped to a SQL Anywhere data type that has a greater range of possible values. As a result, it is possible to pass a value to SQL Anywhere that will be accepted and stored in a database, but one that is too large to be fetched by an Open Client application.

The tables in the section "Data type mappings between systems", outline which Open Client data types are matched to SQL Anywhere data types and visa versa.

The data types listed in the following table have the potential to cause errors because of the range of possible values.

Example

For example, the Open Client Money and smallmoney data types do not span the entire numeric range of their underlying SQL Anywhere implementations. Therefore it is possible to have a value in a SQL Anywhere column which exceeds the boundaries of the Open Client data type money. When the client fetches any such offending values via the Open Server Gateway, an error will occur ("Open Server Gateway Error 22: Invalid data format. Possible overflow or underflow").

The implementation in SQL Anywhere of Open Client's timestamp data type, when such a value is passed in SQL Anywhere (the value is mapped to SQL Anywhere's datetime data type), is very different from that of SQL Server's. The default value is NULL, and hence no guarantees are made to ensure its uniqueness.

By contrast, the SQL Anywhere timestamp data type contains year, month, day, hour, minute, second and fraction of second information, and the datetime data type has a greater range of possible values than the Open Client data types that are mapped to it by Open Server Gateway.

Data type	Implementation	Lower range	Upper range
money	Open Client applications	-922,337,203,685,477.5808	922,337,203,685,477.5807
decimal (20,4)	SQL Anywhere	-999,999,999,999,999.9999	999,999,999,999,999.9999
smallmoney	Open Client applications	-214,748.3648	214,748.3647
decimal (10,4)	SQL Anywhere	-999,999.9999	999,999.9999
timestamp	Open Client applications	N/A	N/A
datetime	Open Client applications	Jan 1, 1753	Dec 31, 9999
smalldatetime	Open Client applications	Jan 1, 1900	June 6, 2079
datetime	SQL Anywhere	Jan 1, 0001	Dec 31, 9999
bit	Open Client applications	0	1
tinyint	SQL Anywhere	0	255
Other restrictions

SQL Anywhere defines sysname as varchar (30) and does not allow the Open Server client application to specify the length of the data field.


Open Client data types with description limitations
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 31. Using the Open Server Gateway

Data type mappings

Open Client data types with description limitations

Except for the issues raised in "Data types with value range limitations", the data types listed in the following table will not cause any problems so long as the Open Client application can handle having the data result returned in a different data type format. If these applications force the data to be converted to the original, expected data type, no problems will occur. However, most Open Client applications tend to bind to the data type described by the Open Server.

Open Client data type	SQL Anywhere 5.501 and previous releases	SQL Anywhere 5.502 and beyond
bit	tinyint	tinyint
sysname	varchar (30)	varchar (30)
timestamp	datetime	datetime
smalldatetime	datetime	datetime
decimal*	decimal	numeric
decimal (20,4)	decimal (20,4)	money
decimal (10,4)	decimal (10,4)	smallmoney
numeric (20,4)	decimal (20,4)	money
numeric (10,4)	decimal (10,4)	smallmoney
binary	binary	varbinary
* The data mapping of Decimal data types applies to all precisions, except Decimal (20,4) and Decimal (20,4) as noted in the above table.


Incompatible Open Client data types
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 31. Using the Open Server Gateway

Data type mappings

Incompatible Open Client data types

The following tables lists Open Client data types for which there is no, or limited, support in SQL Anywhere.

Open Client application data type	Problem
float	When used in SQL statements, 'float' is interpreted as 'real'
long	Not supported
sensitivity	Not supported
boundary	Not supported
void	Not supported


Setting up the Open Server Gateway
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 31. Using the Open Server Gateway

Setting up the Open Server Gateway

Whenever you run Open Server Gateway for SQL Anywhere, you provide a server name on the command line that identifies the Open Server Gateway to client applications. This server name must be recognized by client applications in order for them to communicate with the Open Server Gateway.

Typically, you may provide an Open Server Gateway name that is the same as the name of the SQL Anywhere server to which it is connected. You need to add each Open Server Gateway name to your list of Open Servers. You can do this from the Sybase SQLEDIT utility for managing network connection information for Open Servers.

This section describes the steps in using SQLEDIT to add an Open Server Gateway to your list of Open Servers. It is not complete SQLEDIT documentation. The SQLEDIT utility is provided with Sybase Net-Library.

Required information

For each Open Server, you must provide the following information:

♦	Server name The name of the Open Server, which you set when starting Open Server Gateway.

♦	Driver The Sybase Net-Library driver DLL to be used for the connection. A different driver is used for each network protocol.

♦	Service type The type of connection for the server. A query service holds connection information used by a client to log in to the server. A master service holds connection information used by a server to listen for connection requests from clients.

♦	Connection information Network address-related information for the specified server.

Add an Open Server

To add an Open Server, choose Add Server from the SQLEDIT Edit menu, and type a name for your Open Server in the space provided. Open Server names are always entered as upper case, but are case insensitive.

You may wish to use the same name for your Open Server Gateway as for the SQL Anywhere database server it is connected to. For example, if you are running a database server on the sample database, with the default name of SADEMO, you may wish to name your Open Server SADEMO.

The default server name for the Open Server Gateway is SQLAny.

Add a QUERY service

You need to add a QUERY service for the Open Server. To add a service, choose Add Service from the Edit menu. In Connection Information, provide the following information:

♦	The network driver used for the connection; for example, TCP/IP Sockets.

♦	The connection's address-related information.

Add a MASTER service

You need to add a MASTER service for the server. The entries you provide for the Network Driver and Connection Information should be the same as for the QUERY service.

A MASTER service is required when the program is running on the current machine. If the program is running on some other computer, you need only a QUERY service.

 Starting the Open Server Gateway

 Open Server Gateway actions on connecting


Starting the Open Server Gateway
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 31. Using the Open Server Gateway

Setting up the Open Server Gateway

Starting the Open Server Gateway

Open Server Gateway is a client application for SQL Anywhere database engines or servers. With a SQL Anywhere database server running, you can run the Open Server Gateway so that client applications using Sybase Open Client architecture can communicate with a SQL Anywhere database server.

The executable name of the Open Server Gateway is DBOS50.EXE. For usage information about the Open Server Gateway, type

DBOS50 -?

  For a full description of the Open Server Gateway command-line switches, see "The Open Server Gateway".

To start the Open Server Gateway for NT or OS/2, using the default command-line switches, type the following from a command line:

start DBOS50 server_name

where server_name is the name of your SQL Anywhere database server. For a SQL Anywhere server named sademo, the command line would be

start DBOS50 sademo

To load the NetWare Open Server Gateway, using the default command-line switches, type the following from a NetWare command line:

load DBOS50.nlm server_name

By default, the Open Server Gateway maintains a log file in the current directory, with name SERVER.WOS where server is the name of the Open Server.

Use verbose mode for debugging only—The Open Server Gateway has a -v command-line switch to run in a verbose mode. In verbose mode, debugging messages are output, including the result sets of any queries executed and so on. Although the verbose mode is useful for debugging purposes, it has a significant effect on performance and should not be used in production environments.

Confirm the Open Server Gateway is configured properly

You can confirm that the Open Server Gateway is running properly by connecting to the database using the Sybase isql utility. Sybase isql connects to SQL Anywhere databases using the Open Server Gateway.

To start isql running on the SQL Anywhere server, type

start isql -U uid -P password -S server_name

where uid is a user ID with DBA permissions, and server_name is the name of your primary site server.

Potential PATH conflict—If the SQL Anywhere installation directory precedes your Sybase installation directory in your path, you will need to type the full path to avoid starting the SQL Anywhere ISQL instead.

To start isql running on the sademo Open Server Gateway, type

start isql -U dba -P sql -S sademo


Open Server Gateway actions on connecting
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 31. Using the Open Server Gateway

Setting up the Open Server Gateway

Open Server Gateway actions on connecting

When Open Server Gateway connects to SQL Anywhere, it automatically sets relevant database options to values that are compatible with SQL Server default behavior. These options are set temporarily, for the duration of the Open Server Gateway connection only. They can be overridden by the client application at any time.

The database options that are set by Open Server Gateway on connection are as follows:

Option	Set to
ALLOW_NULLS_BY_DEFAULT	OFF
ANSI_BLANKS	ON
ANSI_INTEGER_OVERFLOW	ON
AUTOMATIC_TIMESTAMP	ON
CHAINED	OFF
QUOTED_IDENTIFIER	OFF
TSQL_HEX_CONSTANT	ON
TSQL_VARIABLES	ON
  For more information

For more information about available SQL Anywhere database options, see "SET OPTION statement".

For more information about compatibility of SQL Anywhere and SQL Server options, see "Transact-SQL SET statement" and "Setting options for Transact-SQL compatibility".

For more information about making your SQL Anywhere database as compatible as possible with SQL Server, see "Creating a Transact-SQL-compatible database".


Events handled by Open Server Gateway
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 31. Using the Open Server Gateway

Events handled by Open Server Gateway

Sybase Client Library applications send requests to Open Server Gateway. Each request triggers an event, and Open Server Gateway executes a routine to handle that event. The routine that handles an event is called an event handler.

Open Server Gateway functionality is described in terms of these events: the events to which it can respond, and the ways in which it responds to those events.

Events can be of two kinds:

♦	Standard events. Events defined internally in Open Server.

♦	Programmer-defined events. Events defined by the Open Server Gateway application. Open Server Gateway does not support any programmer-defined events.

 Standard event handling in Open Server Gateway

 Known limitations of the Open Server Gateway


Standard event handling in Open Server Gateway
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 31. Using the Open Server Gateway

Events handled by Open Server Gateway

Standard event handling in Open Server Gateway

The following list describes each Open Server standard event, and the Open Server Gateway handling of that event.

♦	SRV_ATTENTION event   This usually occurs when a client calls ct_cancel to stop results processing prematurely. Open Server Gateway checks the status of SRV_ATTENTION between fetches, and stops processing if the event has been received.

♦	SRV_BULK event   A client has inserted a binary large object or has issued a bulk copy request. Inserting binary large opjects is supported, but bulk copies are not supported by Open Server Gateway.

♦	SRV_CONNECT event   A Client-Library client has called ct_connect. Connections to SQL Server are made to the server, and the USE SQL statement sets the current database. Connections to SQL Anywhere are made to an individual database. The -d and -e command-line switches for Open Server Gateway determine the server and database to which connections will be made when a connect event occurs. For more information on the command-line switches, see "The Open Server Gateway".

♦	SRV_CURSOR event   A client has sent a cursor request. This event is supported by Open Server Gateway.

♦	SRV_DISCONNECT event   A request to disconnect a client connection has been made. This event is supported by Open Server Gateway.

♦	SRV_DYNAMIC event   A client has sent a Dynamic SQL request. Dynamic SQL allows a client application to execute SQL statements containing variables whose values are determined at run-time. All the operation types available for the SRV_DYNAMIC event are supported except for the DESCRIBE_INPUT type. The results of a DESCRIBE_INPUT SRV_DYNAMIC event are not complete.

♦	SRV_LANGUAGE event   A client has sent a language request, such as a SQL statement. The SQL statement is passed on to SQL Anywhere. The success of failure of the event depends on whether the SQL statement is supported by SQL Anywhere.

For information about Transact-SQL compatibility in SQL Anywhere, see the chapter "Using Transact-SQL with SQL Anywhere".

♦	SRV_MSG event   A client has sent a message. The message ID and parameters are read, but no action is performed. The success return code is returned to the client application.

♦	SRV_OPTION event   A client has sent an option command. Options that are supported by SQL Anywhere are passed on to the database server. The following options are supported by Open Server Gateway:

♦	date_format   Set the date format for conversion of dates retrieved from the database to strings.

♦	arith_ignore

♦	isolation   Set the isolation level. The isolation level can be set to the SQL Anywhere-supported isolation levels 0, 1, 2, and 3.

♦	quoted_identifier   Set to ON for the default SQL Anywhere and ISO/ANSI SQL/92 behavior; set to OFF for the default SQL Server behavior.

♦	ansi_null

♦	SRV_RPC event   A client has issued a remote procedure call. The procedure is specified as follows:

owner-name.database-name.procedure-name (parameter-list)

Open Server Gateway checks to see if the current database is the correct one, and if so executes the procedure. If the current database is not the correct one, a failure is returned.

♦	SRV_START event   A call to srv_run triggers a SRV_START event. This event is not generated by client applications.

♦	SRV_STOP event   A request to stop Open Server Gateway has been made. This event is not generated by client applications. The dbosstop utility is provided for shutting down the Open Server.

♦	SRV_URGDISCONNECT event   This event is only triggered by an Open Server application calling srv_event. It is not supported by Open Server Gateway.


Known limitations of the Open Server Gateway
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 31. Using the Open Server Gateway

Events handled by Open Server Gateway

Known limitations of the Open Server Gateway

Using the Open Server Gateway, you can use a SQL Anywhere database in much the same way as you would a SQL Server. There are some limitations, including the following:

♦	Commit Service   The Open Server Gateway does not support the SQL Server Commit Service.

♦	Prepare Transaction statement   The Open Server Gateway does not support the SQL Server Prepare Transaction statement used by DB-Library in a two-phase commit application to see if a server is prepared to commit a transaction.

♦	Data types   Not all SQL Anywhere and SQL Server data types are supported in the Open Server Gateway. For a description of data type compatibility, see "Data type mappings".


Using SQL Anywhere with OmniCONNECT
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 31. Using the Open Server Gateway

Using SQL Anywhere with OmniCONNECT

This section describes how to start the Open Server Gateway and SQL Anywhere to work with Sybase OmniCONNECT heterogeneous data access software. It does not provide any documentation on OmniCONNECT itself. See your OmniCONNECT documentation for details of how to configure a new data server and other aspects of managing data servers.

The Open Server Gateway allows Sybase SQL Anywhere data sources to appear for many purposes to client applications as if they were Sybase SQL Server data sources. Using the Open Server Gateway, you can incorporate a SQL Anywhere database into your heterogeneous data sources managed by OmniCONNECT. A SQL Anywhere database together with the Open Server Gateway can be treated, subject to limitations described below, as a SQL Server database.

 Setting up SQL Anywhere as an OmniCONNECT remote server

 Limitations of using SQL Anywhere with OmniCONNECT


Setting up SQL Anywhere as an OmniCONNECT remote server
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 31. Using the Open Server Gateway

Using SQL Anywhere with OmniCONNECT

Setting up SQL Anywhere as an OmniCONNECT remote server

This section describes how to set up the Open Server Gateway and SQL Anywhere to work with OmniCONNECT.

 To set up SQL Anywhere as an OmniCONNECT remote server:

1	Start the SQL Anywhere database engine or server running on the database you wish to use. The database must be created with SQL Anywhere Release 5.5.01 or later.

2	Configure and start the Open Server Gateway running against the database. For information on how to do this, see "Starting the Open Server Gateway".

3	Run the OmniCONNECT system procedure sp_addserver to add the new remote server. The SQL Anywhere database should be added with server class SQL_server. OmniCONNECT detects the new server as  a post-System 10 SQL Server.

For example, if you started the Open Server Gateway on the sample database as follows:

dbos50 -d sademo SQLAny_1

then the following OmniCONNECT command line would add the new server:

exec sp_addserver SQLAny_1 sql_server, SQLAny_1

4	If there is no user on the SQL Anywhere database  with identical user ID and password to the OmniCONNECT user, you must add an external login. For example:

exec sp_addexternallogin SQLAny_1 sa, dba, sql

5	Define the objects as for other OmniCONNECT data sources. For example, to define a table named employee in the SQL Anywhere sample database on the Open Server Gateway server SQLAny_1 and owned by User3, you use the following OmniCONNECT command (all on one line):

exec sp_addobjectdef employee, "SQLAny_1.sademo.user3.employee", "table"


Limitations of using SQL Anywhere with OmniCONNECT
User's Guide

PART 4. Transact-SQL Compatibility

CHAPTER 31. Using the Open Server Gateway

Using SQL Anywhere with OmniCONNECT

Limitations of using SQL Anywhere with OmniCONNECT

The following are known limitations when using SQL Anywhere with OmniCONNECT:

♦	Bulk inserts   Bulk inserts are not supported.

♦	Object case sensitivity   Database identifiers (column names, table names, and so on) are treated as case insensitive. String constants are also case-insensitive by default, but for databases created with case-sensitive string comparisons (indicated by using the DBINIT -c command-line switch, or the appropriate SQL Central field), these are case sensitive.

♦	defgen   The OmniCONNECT defgen utility for extracting table definitions is not supported by SQL Anywhere.

♦	Unsupported data types   The NCHAR, NVARCHAR, and TIMESTAMP data types are not supported.


The SQL Anywhere Programming Interfaces
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

SQL Anywhere supports four different programming interfaces.  This part describes each interface in turn.

 CHAPTER 32. Programming Interfaces

 CHAPTER 33. The Embedded SQL Interface

 CHAPTER 34. ODBC Programming

 CHAPTER 35. The WSQL DDE Server

 CHAPTER 36. The WSQL HLI Interface


Programming Interfaces
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 32. Programming Interfaces

There are several programming interfaces to SQL Anywhere:

♦	"ODBC Programming"

♦	"The Embedded SQL Interface"

♦	"The WSQL DDE Server"

♦	"The WSQL HLI Interface"

Embedded SQL

Embedded SQL is a system in which SQL commands are embedded right in a C or C++ source file. A preprocessor is run which translates these statements into calls to a runtime library. Embedded SQL is an ANSI and IBM standard. It is portable to other databases and other environments. Embedded SQL is the lowest level interface to the SQL Anywhere database engine and is functionally equivalent in all operating environments. It provides all functionality that is available in the product. Embedded SQL is quite easy to work with, although it takes a little getting used to the idea of Embedded SQL statements (rather than function calls) in C code.

ODBC

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. You should use ODBC if you would like your application to be portable to other data sources that have ODBC drivers. Also, if you prefer working with an API, use ODBC. The ODBC interface is fairly low level—about the same as Embedded SQL. Almost all of the SQL Anywhere functionality is available with this interface. ODBC is available as a DLL under Windows, OS/2 and Windows NT and as a library for DOS and QNX.

Dynamic Data Exchange

The Dynamic Data Exchange (DDE) Server can be used from Windows applications that provide DDE client services. Some examples are Microsoft Word, Microsoft Excel and Lotus 1-2-3 for Windows. The DDE interface is set oriented — the entire results of a query are returned to the application at once. The results are returned on the clipboard or in memory. Use the DDE interface from any Windows application that has DDE support and can handle a set of information being returned.

High-level interface (HLI)

The WSQL HLI Dynamic Link Library (DLL) provides a simple, high-level interface to SQL Anywhere in Windows, OS/2 or Windows NT. It is either set or record-at-a-time oriented. You can choose how you would like to retrieve results. The record-at-a-time interface provides more control for use in systems like Visual Basic where data entry applications are being built. You can use the DLL from any application that supports linkage to a DLL. You can also use this DLL from any programming language. If this DLL does not provide everything you need, use the ODBC interface (also a DLL).


The Embedded SQL Interface
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

About this chapter

This chapter describes the Embedded SQL interface to SQL Anywhere database engines.

Structure packing must be turned on—All Embedded SQL programs must be compiled with the structure packing option of the compiler set to one-byte alignment (usually the default).

 The C language SQL preprocessor

 Embedded SQL interface data types

 Host variables

 The SQL communication area (SQLCA)

 Fetching data

 Static vs dynamic SQL

 The SQL descriptor area (SQLDA)

 SQL procedures in Embedded SQL

 Library functions

 Interface library DLL dynamic loading

 Embedded SQL commands

 Database examples

 SQLDEF.H header file


The C language SQL preprocessor
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

The C language SQL preprocessor

Embedded SQL consists of SQL statements intermixed with C or C++ source code. These SQL statements are translated by the Embedded SQL preprocessor into C source code. This code, in conjunction with the database interface dynamic link library (normal library in DOS or QNX), will communicate the appropriate information to the database engine when the program is run. In the compile and link process, the preprocessor is run before the C program is compiled.

♦	"Supported compilers"

♦	"Development process for Windows 3.x and 95, OS/2, or Windows NT"

♦	"Development process for DOS or QNX"

♦	"Running the SQL preprocessor"

♦	"Embedded SQL header files"

♦	"Embedded SQL libraries"

♦	"A simple example"

♦	"Structure of Embedded SQL programs"

♦	"Authorization"

 Supported compilers

 Development process for Windows 3.x and 95, OS/2, or Windows NT

 Development process for DOS or QNX

 Running the SQL preprocessor

 Embedded SQL header files

 Embedded SQL libraries

 A simple example

 Structure of Embedded SQL programs

 Authorization


Supported compilers
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

The C language SQL preprocessor

Supported compilers

The C language SQL preprocessor has been used in conjunction with the following compilers:

Windows 3.x compilers

♦	Watcom C/C++ 9.0 and above.

♦	Microsoft C 5.0, 5.1, 6.0

♦	Microsoft C++ 7.0

♦	Microsoft Visual C++ 1.0, 1.5

♦	Borland C++ 2.0, 3.0, 4.0, 4.5

DOS compilers

♦	Watcom C/C++ 9.5 and above.

♦	Microsoft C 6.0, 7.0

♦	Microsoft Visual C++ 1.0, 1.5

♦	Borland C++ 3.0, 4.0

♦	Turbo C 2.0

OS/2 compilers

♦	Watcom C/C++ 9.0 and above.

♦	IBM C Set ++ 2.0

♦	Borland C++ for OS/2 1.0

Windows 95 and NT compilers

♦	Watcom C/C++ 9.5 and above.

♦	Microsoft Visual C++ 1.0, 1.5, 2.0, 4.0, 4.1

♦	Borland C++ 4.5

QNX compiler

♦	Watcom C 9.5 and above.

The following sections present the development process required to build Embedded SQL programs. A section on running the SQL preprocessor is followed by a simple example. The remaining sections present various topics fundamental to the creation of Embedded SQL programs.

Structure packing must be turned on—All Embedded SQL programs must be compiled with the structure packing option of the compiler set to one-byte alignment (usually the default).


Development process for Windows 3.x and 95, OS/2, or Windows NT
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

The C language SQL preprocessor

Development process for Windows 3.x and 95, OS/2, or Windows NT

The SQL runtime interface is implemented as a DLL (dynamic link library) for Windows, OS/2 and Windows NT. One Windows import library works for all compilers and memory models. One OS/2 import library works for all compilers and memory models. For Windows 95 and Windows NT, there are import libraries for WATCOM C, for Microsoft Visual C++, and for Borland C++.

Once the program has been successfully preprocessed and compiled, it is linked with the import library for the SQL Anywhere dynamic link library (DLL) to form an executable file. When the database is running (see "The database engine"), this executable file will use the SQL Anywhere DLL to interact with the database. The database does not have to be running when the program is preprocessed.

WATCOM C supports 32-bit application development under Windows 3.x. For this environment, an interface library (not a DLL) is provided.

The development process is then the same as DOS.


Development process for DOS or QNX
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

The C language SQL preprocessor

Development process for DOS or QNX

Once the program has been successfully preprocessed and compiled, it is linked with the SQL runtime library to form an executable file. When the database is running (see "The database engine".) this executable file will interact with the database. The database does not have to be running when the program is preprocessed.

The SQL runtime library is available in various memory models. Not all libraries are provided on the distribution diskettes. "Embedded SQL libraries" lists which libraries are provided, how they are named and where they can be found.


Running the SQL preprocessor
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

The C language SQL preprocessor

Running the SQL preprocessor

Normally, SQLPP is run as follows:

SQLPP [ switches ] sql-filename [output-filename]

The SQL preprocessor processes a C program with Embedded SQL before the C compiler is run. SQLPP translates the SQL statements 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 sql-filename with an extension of C. If the sql-filename already has a .C extension, then the output filename extension will be CC by default.

The command-line switches for SQLPP are documented in "SQL Anywhere Components". In summary, they are as follows:

SQLPP [switches] sql-filename [output-filename]

   -c         Favor code size

   -d         Favor data size

   -f         Put far keyword on generated static data

   -l userid,pswd   Logon identification

   -n         Line numbers

   -o          operating-sys

            Target operating system specification

            DOS, DOS32, DOS286, WINDOWS, WIN32

            OS232, WINNT, NETWARE, QNX32

            (default is DOS, OS232, or WINNT)

   -r         generate reentrant code

   -q         Quiet mode—do not print banner

   -s string-len   Maximum string constant length for compiler


Embedded SQL header files
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

The C language SQL preprocessor

Embedded SQL header files

All header files are installed in the H subdirectory of the SQL Anywhere directory. For QNX they are in the INCLUDE subdirectory.

Structure packing must be turned on—All Embedded SQL programs must be compiled with the structure packing option of the compiler set to one-byte alignment (usually the default).

Filename	Description
SQLCA.H	Main SQL Anywhere 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 engine or SQL Anywhere Client 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.


Embedded SQL libraries
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

The C language SQL preprocessor

Embedded SQL libraries

All interface libraries are installed in a subdirectory of the SQL Anywhere installation directory (usually C:\SQLANY50). For QNX the standard installation directory is /usr/lib/sqlany50.

The DOS\LIB directory contains the following import libraries:

♦	DBLIBWCC.LIB   DOS WATCOM C compact memory model library.

♦	DBLIBWCH.LIB   DOS WATCOM C huge memory model library.

♦	DBLIBWCL.LIB   DOS WATCOM C large memory model library.

♦	DBLIBWCM.LIB   DOS WATCOM C medium memory model library.

♦	DBLIBWCS.LIB   DOS WATCOM C small memory model library.

♦	DBLIBMCC.LIB   DOS Microsoft C compact memory model library.

♦	DBLIBMCH.LIB   DOS Microsoft C huge memory model library.

♦	DBLIBMCL.LIB   DOS Microsoft C large memory model library.

♦	DBLIBMCM.LIB   DOS Microsoft C medium memory model library.

♦	DBLIBMCS.LIB   DOS Microsoft C small memory model library.

♦	DBLIBBCC.LIB   DOS Borland C compact memory model library.

♦	DBLIBBCH.LIB   DOS Borland C huge memory model library.

♦	DBLIBBCL.LIB   DOS Borland C large memory model library.

♦	DBLIBBCM.LIB   DOS Borland C medium memory model library.

♦	DBLIBBCS.LIB   DOS Borland C small memory model library.

♦	DBLIBWFG.LIB   32-bit Rational DOS4G DOS Extender WATCOM C library.

♦	DBLIBWFP.LIB   32-bit Pharlap DOS Extender WATCOM C library.

The WIN\LIB directory contains the following import libraries:

♦	DBLIBW.LIB   Windows import library for DBLIBW.DLL

♦	DBLIBWFW.LIB   32-bit Windows WATCOM C library.

♦	DBLIBFWS.LIB   32-bit Windows WATCOM C stack calling convention library.

The OS2\LIB directory contains the following import library:

♦	DBLIB2.LIB   OS/2 import library for DBLIB2.DLL

The WIN32\LIB directory contains the following import libraries:

♦	DBLIBTW.LIB   Windows 95 and NT WATCOM C/C++ import library for the Embedded SQL interface library.

♦	DBLIBTB.LIB   Windows 95 and NT Borland C++ import library for the Embedded SQL interface library.

♦	DBLIBTM.LIB   Windows 95 and NT Microsoft Visual C++ import library for the Embedded SQL interface library.

The qnx/lib directory contains the following files:

♦	dblib3r.lib   32-bit QNX WATCOM C library.


A simple example
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

The C language SQL preprocessor

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 );

   return( -1 );

}

This example connects to the database, updates the surname of employee number 1056, 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) will be executed after any SQL statement that causes an error.

Note that the first section of this chapter uses UPDATE and INSERT examples because they are simpler. "Fetching data" will discuss fetching data.


Structure of Embedded SQL programs
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

The C language SQL preprocessor

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 engine and to specify the userid that will be used for authorizing all statements executed during the connection (see "Authorization" below).

There are two kinds of ordering on statements:—These are the order in which they appear in the source file, and the order in which they are executed when the program is run.

As noted above, the CONNECT statement must be the first executed. Note that 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 notably are the INCLUDE statement and the WHENEVER statement for specifying error processing.


Authorization
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

The C language SQL preprocessor

Authorization

The CONNECT statement specifies a userid and password that will be used for checking the authorization of any dynamic SQL statements used in the program (defined in "Dynamic statements" ). It will also be used for authorization of any static statements contained in modules which were preprocessed without the -l option on the SQLPP command line.

Static SQL statements in modules preprocessed with the -l option will have the authorization checked at execution time using the userid and password specified with the -l option. This is how privileged commands can be executed by non-privileged users under C program control.


Embedded SQL interface data types
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Embedded SQL interface data types

In order to transfer information between a program and the database engine, every piece of data must have a data type. The following data types are supported by the embedded SQL programming interface. The Embedded SQL data type constants (prefixed with DT_) can be found in the SQLDEF.H header file (see "SQLDEF.H header file"). You can create a host variable (next section) of any one of these types. You can also use these types in an SQLDA structure (described later) for passing data to and from the database.

Data type constant	Description
DT_SMALLINT	16 bit, signed integer.
DT_INT	32 bit, signed integer.
DT_FLOAT	4 byte floating point number.
DT_DOUBLE	8 byte floating point number.
DT_DECIMAL	Packed decimal number. Decimal digits are packed into an array of characters, two digits per byte. The most significant digits are stored first. The low order nibble (half-byte) of the last byte is the sign (0xC for positive, 0xD for negative). If the precision is even, the first digit stored is a 0. typedef struct DECIMAL { char array[1];  } DECIMAL;
DT_STRING	NULL-terminated character string.
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. The length field must be set when supplying information to the database engine. The database engine will set the length field when you fetch information. typedef struct VARCHAR { unsigned short int len; char array[1]; } VARCHAR;
DT_BINARY	Varying length binary data with a two byte length field. The length field must be set when supplying information to the database engine. The database engine will set the length field when you fetch information. typedef struct BINARY { unsigned short int len; char array[1]; } BINARY;
DT_TIMESTAMP_STRUCT	SQLDATETIME structure with fields for each part of a timestamp. typedef struct sqldatetime { unsigned short year; /* e.g. 1992 */ 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 struct 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. See the DATE_FORMAT, TIME_FORMAT, TIMESTAMP_FORMAT, and DATE_ORDER database options in "SET OPTION statement".
DT_VARIABLE	NULL-terminated character string. The character string must be the name of a SQL variable whose value will be used by the database engine (see "SET statement"). This data type is only used when supplying data to the database engine. It cannot be used when fetching data from the database engine.
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.

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.

There are no embedded SQL interface data types for LONG VARCHAR and LONG BINARY database types. These database types are fetched and updated in pieces. For more information see "GET DATA statement" and "SET statement".


Host variables
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Host variables

Host variables are C variables which are identified to the SQL preprocessor. Host variables can be used to send values to the database engine or receive values from the database engine.

Host variables are quite easy to use, but they have some restrictions. "Static vs dynamic SQL" describes dynamic SQL and the more general way of passing information to and from the database engine using a structure known as the SQL Descriptor Area (SQLDA). This section contains information on the following topic:

♦	"Host variable declarations"

♦	"C host variable types"

♦	"Host variable usage"

♦	"Indicator variables"

 Host variable declarations

 C host variable types

 Host variable usage

 Indicator variables


Host variable declarations
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Host variables

Host variable declarations

Host variables are defined by putting them into a declaration section. According to the IBM SAA and the ANSI Embedded SQL standards, host variables are defined by surrounding the normal C variable declarations with:

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 engine executes the command, the value of the host variable will be 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 an 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.

The following is an example of 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 see "Static cursor example".


C host variable types
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Host variables

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.

There are macros defined in the SQLCA.H header file that can be used to declare a host variable of these types: VARCHAR, FIXCHAR, BINARY, PACKED DECIMAL, or SQLDATETIME structure. They 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 will treat the variable as the appropriate type.

The following table illustrates C variable types 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
char *a;	DT_STRING(32767)	NULL-terminated string- see note
DECL_VARCHAR(n) a;	DT_VARCHAR(n)	varying length character string with 2 byte length field
DECL_BINARY(n) a;	DT_BINARY(n)	varying length binary data with 2 byte length field
DECL_DATETIME a;	DT_TIMESTAMP_STRUCT	SQLDATETIME structure
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. Thus, you must ensure that any host variable of type pointer to char used to retrieve information from the database points to a buffer large enough to hold any value that could possibly come back from the database. Note that this is potentially quite dangerous as 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 result in overflowing the program stack. 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 (a warning will result). The SQL preprocessor has one exception to this rule. It will allow two host variables of the same name if they have identical types (including any necessary lengths).


Host variable usage
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Host variables

Host variable usage

♦	Host variables can be used in SELECT, INSERT, UPDATE and DELETE statements in any place where a number or string constant is allowed.

♦	Host variables can be used in 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 Embedded SQL specific commands.

♦	For CONNECT, DISCONNECT, and SET CONNECT a host variable can be used in place of a userid, password, connection name or database environment name.

♦	For SET OPTION and GET OPTION, a host variable can be used in place of a userid, option name or option value.

♦	Host variables cannot be used in place of a table name or a column name in any statement.

For releases starting with 5.0.02, you can declare SQLSTATE and SQLCODE as host variables within a declare section.  This is provided for ISO/ANSI compatibility.

Before release 5.0.02, SQLSTATE and SQLCODE were macros for values in the sqlca, and this is still true if neither is specified in your program. However, if you declare SQLSTATE or SQLCODE anywhere in the program, then the macro definitions are removed. This means that if a program contains a declaration of SQLCODE/SQLSTATE, then a SQLSTATE/SQLSTATE must be within the scope of every embedded SQL statement in the program.

Examples

The following is a valid program:

INCLUDE SQLCA;

long SQLCODE;

sub1() {

   char SQLSTATE[6];

   exec sql CREATE TABLE ...

}

The following is an invalid program:

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
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Host variables

Indicator variables

The NULL value is a value that can be put into certain columns in the database. It represents either an unknown attribute or inapplicable information. See "NULL value" for a complete description of NULLs.

NULL in SQL and C—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 this book, it refers to the SQL database meaning given above. The C language constant will be 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. An indicator variable is a host variable of type short int that is placed immediately following a regular host variable in an SQL statement. For example, the previous insert statement example 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 );

In this example, a NULL is assigned to the phone number if the phone number is unknown. This is accomplished by assigning negative one (-1) to the indicator variable.

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, then an error is generated (SQLE_NO_INDICATOR). Errors are explained in the next section.

Indicator variables are also used to indicate whether any fetched values were truncated to fit into the host variables (indicator has positive value). In this case, the indicator variable contains the actual length of the database value before truncation. If the length of the value is greater than 32767, then the value must be truncated and the indicator variable contains 32767.

  For more information on retrieving long values, see "GET DATA statement".

See the following table for a more complete description 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
= -1	NULL value	NULL result
= -2	NULL value	Conversion error SQLCODE will indicate a conversion error
< -2	NULL value	NULL result


The SQL communication area (SQLCA)
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

The SQL communication area (SQLCA)

The SQL Communication Area (SQLCA) is an area of memory used on every database request for communicating statistics and errors from the application to the database engine and back to the application. There is a global SQLCA variable defined in the interface library (imports library for the DLLs). An external reference for this variable named sqlca of type SQLCA and an external reference for a pointer to this variable sqlcaptr are automatically generated by the preprocessor. The actual global variable is declared in the database library (imports library for DLLs).

Structure packing option—All Embedded SQL programs must be compiled with the structure packing option of the compiler set to one-byte alignment (usually the default).

typedef long int      an_sql_code;

typedef char an_sql_state[6];

struct sqlwarn{ unsigned char sqlwarn0;

   unsigned char   sqlwarn1;

   unsigned char   sqlwarn2;

   unsigned char   sqlwarn3;

   unsigned char   sqlwarn4;

   unsigned char   sqlwarn5;

   unsigned char   sqlwarn6;

   unsigned char   sqlwarn7;

   unsigned char   sqlwarn8;

   unsigned char   sqlwarn9;

};

typedef struct sqlca {

   unsigned char sqlcaid[8];

   long sqlcabc;

   an_sql_code sqlcode;

   short sqlerrml;

   unsigned char sqlerrmc[70];

   unsigned char sqlerrp[8];

   long sqlerrd[6];

   struct sqlwarn   sqlwarn;

   an_sql_state   sqlstate;

} SQLCA;

#define SQLCODE sqlcaptr->sqlcode

#define SQLSTATE sqlcaptr->sqlstate

#define SQLIOCOUNT sqlcaptr->sqlerrd[1]

#define SQLCOUNT sqlcaptr->sqlerrd[2]

#define SQLIOESTIMATE sqlcaptr->sqlerrd[3]

The user references 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). As shown in there are some C macros defined for referencing the sqlcode field, the sqlstate field and some other fields.

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 engine. It is implicitly passed on all Embedded SQL statements.

The fields in the SQLCA have the following meanings:

Field	Description
sqlcaid	An 8 byte character field that contains the string "SQLCA   " as an identification of the SQLCA structure. This field helps in debugging when looking at memory contents.
sqlcabc	A long integer containing the length of the SQLCA structure (136 bytes).
sqlcode	A long integer specifying 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. These error codes are fully explained in he chapter "SQL Anywhere Database Error Messages". The error code will be 0 for a successful operation, positive for a warning and negative for an error.
sqlerrml	The length of the information in the sqlerrmc field.
sqlerrmc	May contain one or more character strings to be inserted into an error message. See "SQL Anywhere Database Error Messages" for a list of the error codes and the error messages. Some error messages have a %1 in them which is replaced with the text in this field. For example, if a table not found error is generated, this field will contain the table name which is inserted into the error message at the appropriate place.
sqlerrp	Reserved.
sqlerrd	A utility array of longs.
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 the digits '0' through '9' or the upper case alphabetic characters '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. Other SQLSTATE values used by SQL Anywhere are described in "SQL Anywhere Database Error Messages".
The sqlerror field array has the following elements.

Element	Description
sqlerrd[1] (SQLIOCOUNT)	The actual number of input/output operations 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 will be the total number of input/output operations for the entire command sequence.
sqlerrd[2] (SQLCOUNT)	The number of rows affected by the command (for INSERT, UPDATE and DELETE). 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 will be the actual number of rows if the database engine can compute it without counting the rows. The database can also be configured to always return the actual number of rows (see "SET OPTION statement"). On a FETCH cursor statement, this field is filled if a SQLE_NOTFOUND warning is returned. It will contain the number of rows that the a FETCH RELATIVE or FETCH ABSOLUTE statement has exceeded the allowable cursor positions. (A cursor can be on a row, before the first row or after the last row.) 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 will be positive if the attempted fetch was further beyond the end of the cursor, and negative if the attempted fetch was further before the beginning of the cursor. On a GET DATA statement, this field holds the actual length of the value. In the case of a syntax error, SQLE_SYNTAX_ERROR, this field will contain the approximate character position within the command string where the error was detected..
sqlerrd[3] (SQLIOESTIMATE)	The estimated number of input/output operations required to complete the command. This field is filled in on an OPEN or EXPLAIN command.


Fetching data
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

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.

♦	The SELECT statement may return multiple rows.

The next two sections describe these cases.

Fetches retrieving multiple rows at a time are also allowed, and may improve performance. These are discussed in "Fetching more than one row at a time".

 Embedded SELECT

 Cursors in Embedded SQL


Embedded SELECT
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Fetching data

Embedded SELECT

Single row queries retrieve at most one row from the database. This type of query is achieved by embedding a normal SQL SELECT statement with an INTO clause. The INTO clause follows the select list and precedes the FROM clause. It 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 a SELECT statement is executed, the database engine retrieves the results of the select statement and places the results in the host variables. If the query results contain more than one row, the database engine will return an error. In this case, cursors must be used (see next section). 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 described in "The SQL communication area (SQLCA)".

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         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 */

   }

}


Cursors in Embedded SQL
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Fetching data

Cursors in Embedded SQL

A cursor is used to retrieve rows one at a time from a query that has multiple rows in the result set. A cursor is a handle or an identifier for the SQL query and a position within the results. Managing a cursor is similar to managing files in a programming language. The following steps are used to manage cursors:

♦	A cursor is declared for a particular select statement using the DECLARE statement.

♦	The cursor is opened using the OPEN statement.

♦	The FETCH statement is used to retrieve results one row at a time from the cursor.

♦	Usually records are fetched until the Row Not Found warning is returned. Errors and warnings are returned in the SQLCA structure described in "The SQL communication area (SQLCA)". The cursor is then closed 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 will be kept open for subsequent transactions until they are explicitly closed.

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;

   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 example" and "Dynamic cursor example".

Cursor positioning

A cursor is positioned in one of three places:

♦	On a row

♦	Before the first row

♦	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" ). 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 will be 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 engine 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 SQL Anywhere, this occurs if a temporary table had to be created to open the cursor (see "Temporary tables used 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 that uses an existing index (a temporary table is not created).


Static vs dynamic SQL
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Static vs dynamic SQL

There are two ways to embed SQL statements into a C program:

♦	"Static statements"

♦	"Dynamic statements"

 Static statements

 Dynamic statements

 Dynamic SELECT statement

 Fetching more than one row at a time


Static statements
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Static vs dynamic SQL

Static 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 the section.Host variables. All examples to this point have used static Embedded SQL statements. Remember that 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 do those operations).

The following commands can be used statically:

ALTER TABLE	INSERT
CHECKPOINT	PREPARE TO COMMIT
COMMIT	RELEASE SAVEPOINT
COMMENT	REVOKE
CONNECT	ROLLBACK
CREATE	ROLLBACK TO SAVEPOINT
DELETE	SAVEPOINT
DISCONNECT	SET CONNECTION
DROP	SET OPTION
EXPLAIN	UPDATE
GRANT	VALIDATE TABLE
The SELECT statement is different in Embedded SQL than in interactive SQL  (ISQL).

As described earlier, if the SELECT statement retrieves only one row from the database, then the statement can be coded as a normal SELECT command except that an INTO clause must follow the select list. If the select statement retrieves multiple rows from the database, then a cursor must be used for the select command as described previously.


Dynamic statements
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Static vs dynamic SQL

Dynamic statements

Dynamic statements are SQL statements which are constructed in C language strings. (In the C language, strings are stored in arrays of characters.) These statements can then be executed using the Embedded SQL 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.

In order to pass information between the statements and the C language variables, a data structure called the SQL Descriptor Area (SQLDA) is used (see "The SQL descriptor area (SQLDA)"). This structure will be 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 prepared command string.

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.

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 that SQLDA in the USING clause on the EXECUTE command. The DESCRIBE BIND VARIABLES statement will return the host variable names of the bind variables 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 );

The SQLDA consists of an array of variable descriptors (see "The SQL descriptor area (SQLDA)" for a complete description of the SQLDA structure). Each descriptor describes the attributes of the corresponding C program variable or location at which the database will store data into or retrieve data from:

♦	data type,

♦	length if type is a string type,

♦	precision and scale if type is a numeric type,

♦	memory address,

♦	indicator variable.

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 engine 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. See "Indicator variables" for more information.


Dynamic SELECT statement
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Static vs dynamic SQL

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 an SQLDA that is specified on the fetch statement (FETCH INTO hostlist and FETCH USING DESCRIPTOR sqlda). 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 will set up an 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 using the FETCH USING DESCRIPTOR statement. The typical scenario is:

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 will be 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;

   if( SQLCODE == SQLE_NOTFOUND ) break;

   /* do something with data */

}

EXEC SQL CLOSE C1;

EXEC SQL DROP STATEMENT S1;

Drop statements after use—You should ensure that statements are dropped after use, to avoid consuming unnecessary resources.

  For a complete example using cursors for a dynamic select statement , see "Dynamic cursor example". For details of the functions mentioned above, see "Library functions".


Fetching more than one row at a time
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Static vs dynamic SQL

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.

SQL Anywhere also supports wide puts and inserts. For information on these, see "PUT statement" and "EXECUTE statement".

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 will be placed in SQLDA variables 0 to (columns per row)-1 and so on.

The engine returns in SQLCOUNT the number of records fetched and will always return a SQLCOUNT greater than zero unless there is an error. Older versions of the engine or server will only return a single row and the SQLCOUNT will be set to zero. Thus a SQLCOUNT of zero with no error condition indicates one valid row has been fetched.

The following example code illustrates the use of wide fetches. The example code is not compilable as it stands.

EXEC SQL BEGIN DECLARE SECTION;

static unsigned             FetchWidth;

EXEC SQL END DECLARE SECTION;

static SQLDA * DoWideFetches( a_sql_statement_number  stat0,

                              unsigned                *num_of_rows,

                              unsigned                *cols_per_row )

/*********************************************************************/

// Allocate an 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 retrieved per row is assigned to "cols_per_row".

{

    int                     num_cols;

    unsigned                i, j, 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 * *num_of_rows) > sqlda->sqln ) {

        free_sqlda( sqlda );

        sqlda = alloc_sqlda( num_cols * width );

        if( sqlda == NULL ) return( NULL );

        EXEC SQL DESCRIBE :stat INTO sqlda;

    }

    sqlda->sqld = num_cols * *num_of_rows;

    offset = num_cols;

    for( i = 1; i < width; ++i ) {

        for( j = 0; j < num_cols; ++j, ++offset ) {

            sqlda->sqlvar[offset].sqltype = sqlda->sqlvar[j].sqltype;

            sqlda->sqlvar[offset].sqllen = sqlda->sqlvar[j].sqllen;

            memcpy( &sqlda->sqlvar[offset].sqlname,

                    &sqlda->sqlvar[j].sqlname,

                    sizeof( sqlda->sqlvar[0].sqlname ) );

        }

    }

    fill_sqlda( sqlda );

    return( sqlda );

}

long DoQuery( char * qry )

/************************/

{

    long                    rows;

    unsigned                cols_per_row;

    SQLDA *                 sqlda;

    EXEC SQL BEGIN DECLARE SECTION;

    a_sql_statement_number  stat;

    static unsigned         num_of_rows;

    EXEC SQL END DECLARE SECTION;

    rows = 0L;

    FetchWidth = 20;

    EXEC SQL WHENEVER SQLERROR GOTO err;

    stmt = qry;

    EXEC SQL PREPARE :stat FROM :stmt;

    EXEC SQL DECLARE QCURSOR CURSOR FOR :stat FOR READ ONLY;

    EXEC SQL OPEN QCURSOR;

    sqlda = DoWideFetches( stat, &num_of_rows, &cols_per_row );

    if( sqlda == NULL ) {

        printf( "Maximum allowable fetch width exceeded\n" );

        return( SQLE_NO_MEMORY );

    }

    for( ;; ) {

        EXEC SQL FETCH QCURSOR INTO DESCRIPTOR sqlda ARRAY :FetchWidth;

        if (SQLCODE != SQLE_NOERROR) break;

    if( SQLCOUNT == 0 ) {

        rows += 1;

    } else {

        rows += SQLCOUNT;

    }

    }

    EXEC SQL CLOSE QCURSOR;

    EXEC SQL DROP STATEMENT :stat;

    free_sqlda( sqlda );

err:

    if (SQLCODE != SQLE_NOERROR) {

        printf( "Error detected\n" );

    }

    return (SQLCODE);

}

Notes on using wide fetches

♦	In 16-bit environments (including extended 32-bit DOS and Windows 3.x) the limit on the size of a SQLDA is 1450 columns. Thus the number of rows times the number of columns per row must be no more than 1450. In these environments, the SQLDA itself (not including data items) must fit in a single 64K segment. alloc_sqlda will return NULL in those environments on an attempt to allocate a SQLDA that is too large.

♦	In the function DoWideFetches, the SQLDA memory is allocated using the alloc_sqlda function, which allows space for indicator variables, rather than using the alloc_sqlda_noind function. This is required, as when fewer than the requested number of rows are fetched (at the end of the cursor, for example) the SQLDA items corresponding to the rows not fetched are returned as NULLs 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 an SQLE_ROW_UPDATED_WARNING warning, the fetch stops on the row which caused the warning and the values for all rows processed to that point (including the row that caused the warning) are returned. SQLCOUNT contains the number of rows fetched and includes 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 read prior to the error, not including the row that caused the error, but the SQLDA does not contain values for those 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.


The SQL descriptor area (SQLDA)
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

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 to and from the database regarding host variables and select statement results. 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 (see "SQLDA management functions").

When host variables are used with static SQL statements, the preprocessor actually constructs an SQLDA for those host variables. It is this SQLDA that is actually passed to and from the database engine.

Structure packing option—All Embedded SQL programs must be compiled with the structure packing option of the compiler set to one-byte alignment (usually the default).

#define SQL_MAX_NAME_LEN 30

typedef short int a_sql_type;

struct sqlname {

   short int length;

   unsigned char data[ SQL_MAX_NAME_LEN ];

 };

struct sqlvar {

   short int sqltype;

   short int sqllen;

   void _sqldafar *sqldata;

   short int _sqldafar *sqlind;

   struct sqlname sqlname;

 };

struct sqlda{

   unsigned char sqldaid[8];

   long int sqldabc;

   short int sqln;

   short int sqld;

   struct sqlvar sqlvar[1];

};

#define SCALE(sqllen) ((sqllen)/256)

#define PRECISION(sqllen) ((sqllen)&0xff)

#define SET_PRECISION_SCALE(sqllen,precision,scale) \

   sqllen = (scale)*256 + (precision)

typedef struct sqlda SQLDA;

typedef struct sqlvar SQLVAR, SQLDA_VARIABLE;

typedef struct sqlname SQLNAME, SQLDA_NAME;

#define SQLDASIZE(n) ( sizeof( struct sqlda ) + \

         (n-1) * sizeof( struct sqlvar) )

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 looking at memory contents.
sqldabc	A long integer containing the length of the SQLDA structure (depends on the size of the array of sqlvar's — 16 + 44*n bytes).
sqln	The number of variable descriptors in the sqlvar array (i.e. how much actual space there is).
sqld	The number of variable descriptors which are valid (i.e. 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 engine.
sqlvar	An array of descriptors of type struct sqlvar each describing a host variable.
The sqlvar fields have the following meanings:

Field	Description
sqltype	The type of the variable described by this descriptor (see "Embedded SQL interface 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 (see "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 engine or retrieving data from the database engine and any necessary type conversion will be 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 and the scale is the number of digits that appear after the decimal point. For more discussion of the length field, see "Length field values".
sqldata	A four-byte pointer to the memory occupied by this variable. The memory pointed to by the sqldata field must correspond to the sqltype and sqllen fields. See "Embedded SQL interface data types" for storage formats. For update and insert commands, this variable will not be involved in the operation if the sqldata pointer is a null pointer. For a fetch, no data is returned if the sqldata pointer is the null pointer.
sqlind	A four-byte 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 (see "Indicator variables"). If the sqlind pointer is the null pointer, then there is no indicator variable pertaining to this host variable. The sqlind field is also used by the DESCRIBE statement to indicate parameter types.
sqlname	A VARCHAR structure containing a length and character buffer. It is filled in on a DESCRIBE statement and is not otherwise used. This field has a different meaning for the two formats of the describe statement: On a DESCRIBE SELECT LIST command, indicator variables, if 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 (see "SQLDEF.H header file"). ♦ 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.
 Length field values


Length field values
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

The SQL descriptor area (SQLDA)

Length field values

The sqllen field length of the SQLVAR struct in an SQLDA is used in 3 different kinds of interactions with the database engine. 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. The types are described in "Embedded SQL interface data types".

Note that in static SQL, an SQLDA is still used but it is generated and completely filled in by the SQL preprocessor. In this static case, the table gives the correspondence between the static C language host variable types and the interface constants.

DESCRIBE

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 engine will perform type conversions between any two types. The memory pointed to by the sqldata field must correspond to the sqltype and sqllen fields.

Database field type	Embedded SQL type returned	Length returned on describe
CHAR(n)	DT_FIXCHAR	n
VARCHAR(n)	DT_VARCHAR	n
BINARY(n)	DT_BINARY	n
SMALLINT	DT_SMALLINT	2
INT	DT_INT	4
TINYINT	DT_TINYINT	1
DECIMAL(p,s)	DT_DECIMAL	high byte of length field in SQLDA set to p and low byte set to s
REAL	DT_FLOAT	4
FLOAT	DT_FLOAT	4
DOUBLE	DT_DOUBLE	8
DATE	DT_DATE	length of longest formatted string
TIME	DT_TIME	length of longest formatted string
TIMESTAMP	DT_TIMESTAMP	length of longest formatted string
LONG VARCHAR	DT_VARCHAR	32767
LONG BINARY	DT_BINARY	32767
Supplying a value

The following table indicates how lengths of values are specified when supplying data to the database engine in the SQLDA.

Only the data types shown in the table are allowed in this case. Note that 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	What program must do to set length when supplying data to the database
DT_STRING	length determined by terminating '\0'
DT_VARCHAR(n)	length taken from field in VARCHAR structure
DT_FIXCHAR(n)	length field in SQLDA determines length of string
DT_BINARY(n)	length taken from field in BINARY structure
DT_SMALLINT	-
DT_INT	-
DT_DECIMAL(p,s)	high byte of length field in SQLDA set to p and low byte set to s
DT_FLOAT	-
DT_DOUBLE	-
DT_DATE	length determined by terminating '\0'
DT_TIME	length determined by terminating '\0'
DT_TIMESTAMP	length determined by terminating '\0'
DT_TIMESTAMP_STRUCT	-
DT_VARIABLE	length determined by terminating '\0'
Retrieving a value

The following table indicates the values of the length field when retrieving data from the database using an SQLDA. The sqllen field is never modified when retrieving data.

Only the interface data types shown in the table are allowed in this case. Note again that the DT_DATE, DT_TIME and DT_TIMESTAMP data types are treated the same as DT_STRING when retrieving information from the database; the value will be formatted as a character string in the current date format.

Embedded SQL Data Type	What program must set length field (sqllen) to when receiving	How database returns length information results from the database after fetching a value
DT_STRING	length of buffer	'\0' at end of string
DT_VARCHAR(n)	maximum length of VARCHAR structure (n+2)	len field of VARCHAR structure set to actual length
DT_FIXCHAR(n)	length of buffer	padded with blanks to length of buffer
DT_BINARY(n)	maximum length of BINARY structure (n+2)	len field of BINARY structure set to actual length
DT_SMALLINT	-	-
DT_INT	-	-
DT_DECIMAL(p,s)	high byte set to p and low byte set to s	-
DT_FLOAT	-	-
DT_DOUBLE	-	-
DT_DATE	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	-	-


SQL procedures in Embedded SQL
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

SQL procedures in Embedded SQL

 Simple procedures

 Procedures with result sets

 Multi-Threaded or Reentrant Code

 Using multiple SQLCAs

 Connection Management with Multiple SQLCAs


Simple procedures
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

SQL procedures in Embedded SQL

Simple procedures

Database procedures can be both created and called from Embedded SQL. A CREATE PROCEDURE statement can be embedded just like any other DDL statement. A CALL statement can also be embedded or it can be prepared and executed. Here is a simple example of 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 retrieve the output variables, you will have to prepare and execute the CALL statement. The next example illustrates the use of host variables. Note the use of both the USING and INTO clause on the execute statement.

EXEC SQL BEGIN DECLARE SECTION;

   double   hv_expense;

   double   hv_balance;

EXEC SQL END DECLARE SECTION;

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;


Procedures with result sets
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

SQL procedures in Embedded SQL

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. Note that 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. Note that 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 will either return the warning SQLE_PROCEDURE_COMPLETE or it will return SQLE_NOERROR indicating there is another cursor. The next 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 female_employees()';

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 (see "Dynamic SELECT statement").

The DESCRIBE statement works fully for procedure calls. A DESCRIBE OUTPUT will produce an SQLDA having a description for each of the result set columns. If the procedure does not have a result set, then the SQLDA will have a description for each INOUT or OUT parameter to the procedure. A DESCRIBE INPUT statement will produce an SQLDA having a description for each IN or INOUT parameter to the procedure.

DESCRIBE ALL is a new form of the DESCRIBE statement that will describe IN, INOUT, OUT and RESULT set parameters. DESCRIBE ALL 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). See "DESCRIBE statement" for a complete description of this functionality.


Multi-Threaded or Reentrant Code
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

SQL procedures in Embedded SQL

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 it's own SQLCA. Any given database connection will only be accessible from one SQLCA.

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 OS/2, Windows NT or Windows 95 application   An OS/2 or Windows NT application can have multiple threads using embedded SQL. If both threads use the same SQLCA, a context switch can cause both threads 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.

♦	Windows DLL   A Windows DLL has only one data segment. While the database engine is processing a request from one application, it may yield to another application that makes a request to the database engine. If your DLL uses the global SQLCA, both applications will be using it at the same time. Each Windows application must have its own SQLCA.

♦	Windows NT, Windows 95 or OS/2 DLL with one data segment   An OS/2 or Windows NT 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 a Windows DLL cannot use the global SQLCA. Each application must have its own SQLCA.

Single SQLCA can handle multiple connections—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.


Using multiple SQLCAs
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

SQL procedures in Embedded SQL

Using multiple SQLCAs

To manage multiple SQLCAs in your application,

♦	You must use the command line switch 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 affects are minimal.

♦	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 serve to fail.

♦	The embedded SQL statement SET SQLCA ("SET SQLCA statement") 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 will use the given string.


Connection Management with Multiple SQLCAs
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

SQL procedures in Embedded SQL

Connection Management with Multiple SQLCAs

Each SQLCA can have one unnamed connection. Each SQLCA has an active or current connection (see "SET CONNECTION statement"). 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 Locks".


Library functions
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

The SQL preprocessor generates calls to functions found in the interface library or DLL. In addition to the calls generated by the SQL preprocessor, there are several routines that are provided for the user to make database operations easier to perform. Prototypes for these functions are included by the EXEC SQL INCLUDE SQLCA command.

Following is a detailed description of these various functions by category. The prototypes given are those used in DOS and QNX.

DLL entry points

The DLL entry points are the same except that the prototypes have a modifier appropriate for DLLs:

♦	Windows:    FAR PASCAL

♦	OS/2:    _System

♦	Windows NT:    __stdcall

All pointers passed as parameters to the Windows DLL entry points or returned by these functions are far pointers.

Example

For example, the first prototype listed below is db_init. For Windows, it would be:

unsigned short FAR PASCAL db_init( struct sqlca far *sqlca );

Passing null pointers—Care should be taken passing the null pointer as a parameter in Windows if your program is compiled in the small or medium memory models. You should use the _sql_ptrchk_() macro defined in SQLCA.H for any pointer parameter which is a variable that might contain the null pointer. This macro converts a null near pointer into a null far pointer.

 Interface initialization functions

 Connection and engine management functions

 SQLDA management functions

 Backup functions

 Other functions

 Aborting a request

 Windows 3.x request management

 Multiple SQLCA management

 Memory allocation in DOS and QNX

 DOS interrupt processing and request management


Interface initialization functions
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Interface initialization functions

This section lists the functions concerned with initializing and releasing the interface.

 db_init function

 db_fini function


db_init function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Interface initialization functions

db_init function

Prototype

unsigned short db_init( struct sqlca *sqlca );

Description

Initializes the database interface library or DLL. This function must be called before any other library call is made and before any Embedded SQL command is executed. Resources required by the interface library 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 will be returned in the SQLCA and 0 will be 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, you need to call db_init once for each SQLCA being used (see "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 serve to fail.


db_fini function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Interface initialization functions

db_fini function

Prototype

unsigned short db_fini( struct sqlca *sqlca );

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. Any errors during processing will be returned in the SQLCA. If there are any errors during processing, they will be returned in the SQLCA and 0 will be returned. If there are no errors, a non-zero value is returned.

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, you need to call db_fini once for each SQLCA being used (see "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 serve to fail.


Connection and engine management functions
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Connection and engine management functions

The following functions provide a means to start and stop the database engine or SQL Anywhere Client (DBCLIENT.EXE), start or stop a database on an existing database engine or network database server; and connect to or disconnect from a database.

All of these functions take a NULL-terminated string as the second argument. This string is a list of parameter settings of the form KEYWORD=value, delimited by semicolons. The number sign "#" is an alternative to the equals sign, and should be used when setting the connection parameters string in the SQLCONNECT environment variable, as using "=" inside an environment variable setting is a syntax error.

The keywords are from the following table.

Verbose keyword	Short form
Userid	UID
Password	PWD
ConnectionName	CON
EngineName	ENG
DatabaseName	DBN
DatabaseFile	DBF
DatabaseSwitches	DBS
AutoStop	AutoStop
Start	Start
Unconditional	UNC
DataSourceName	DSN
Each function uses a subset of these parameters, but every function will allow any parameter to be set. An example connection parameter string is:

"UID=dba;PWD=sql;DBF=c:\sqlany50\sademo.db"

The SQLCONNECT environment variable can be used to specify default values for unspecified parameters (see "Registry entries and environment variables").

 db_string_connect function

 db_string_disconnect function

 db_start_engine function

 db_start_database function

 db_stop_database function

 db_stop_engine function

 db_find_engine function

 db_build_parms function

 db_destroy_parms function

 db_free_parms function

 db_parms_connect function

 db_parms_disconnect function

 db_start function

 db_stop function


db_string_connect function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Connection and engine management functions

db_string_connect function

Prototype

unsigned db_string_connect( struct sqlca * sqlca, char * parms );

Description

Provides extra functionality beyond the Embedded SQL CONNECT command. This function will do the following steps:

♦	Start the database engine if there is not one running with the name EngineName (calls db_start_engine). The AutoStop parameter will determine if the engine will automatically stop when the last used database is shutdown.

♦	If the database named by DatabaseName or DatabaseFile is not currently running, send a request to the engine or network server to start a database using the DatabaseFile, DatabaseName, and DatabaseSwitches parameters. The AutoStop parameter will determine if the database automatically shuts down when the last connection to the database is disconnected.

♦	Send a connection request to the database engine or network server based on the Userid, Password, and ConnectionName parameters.

The return value will be true (non-zero) if a connection was successfully established and false (zero) otherwise. Error information for starting the engine, starting the database or connecting will be returned in the SQLCA.


db_string_disconnect function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Connection and engine management functions

db_string_disconnect function

Prototype

unsigned db_string_disconnect( struct sqlca * sqlca, char * parms );

Description

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 will be disconnected. This is equivalent to the Embedded SQL DISCONNECT command. The boolean return value will be true if a connection was successfully ended. Error information will be returned in the SQLCA.

This function will shut down the database if the database was started with the AutoStop=yes parameter and there are no other connections to the database. It will stop the engine if the engine was started with the AutoStop=yes parameter and there are no other databases running. It will stop the SQL Anywhere Client (DBCLIENT.EXE) if it was started with the AutoStop=yes parameter and there are no remaining connections through the SQL Anywhere Client.


db_start_engine function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Connection and engine management functions

db_start_engine function

Prototype

unsigned db_start_engine( struct sqlca * sqlca,

char * parms );

Description

Start the database engine or SQL Anywhere Client if it is not running. This function carries out the following steps:

♦	Look for a local database engine that has a name that matches the EngineName parameter. If no EngineName is specified, look for the default local database engine (the first database engine started).

♦	Look for the SQL Anywhere Client.

♦	If DatabaseName is specified, look for a local database engine that has a name that matches the DatabaseName parameter.

♦	If DatabaseName is not specified and DatabaseFile is specified, look for a local database engine that matches the root of the file name. For example, if DatabaseFile is C:\SQLANY50\SADEMO.DB, then look for a local engine named sademo.

♦	If no matching local engine is found and the SQL Anywhere Client (DBCLIENT) is not running, start a database engine or SQL Anywhere Client using the Start parameter (or the default start command).

♦	The AutoStop parameter determines if the engine automatically stops when the last database is shut down or if the SQL Anywhere Client automatically stops when its last connection is gone.

The boolean return value is true if a database engine or SQL Anywhere Client was either found or successfully started. Error information will be returned in the SQLCA.

The following call to db_start_engine starts the database engine and names it sademo, but does not load the database, despite the DBF connection parameter:

db_start_engine( &sqlca, "DBF=c:\sqlany50\sademo.db; Start=DBENG50W" );

If you wish to start a database as well as the engine, you must include the database file in the START connection parameter:

db_start_engine( &sqlca,"ENG=eng_name;START=DBENG50W c:\sqlany50\sademo.db" );

This call starts the engine, names it eng_name, and starts the sademo database on that engine.


db_start_database function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Connection and engine management functions

db_start_database function

Prototype

unsigned db_start_database( struct sqlca * sqlca, char * parms );

Description

Start a database on an existing engine or network server if the database is not already running. This function will do the following steps:

♦	Look for a local database engine that has a name that matches the EngineName parameter. If no EngineName is specified, look for the default local database engine.

♦	Look for the SQL Anywhere Client.

♦	If no matching engine or SQL Anywhere Client is found, this function fails.

♦	Send a request to the engine or network server to start a database using the DatabaseFile, DatabaseName and DatabaseSwitches parameters. The AutoStop parameter will determine if the database automatically shuts down when the last connection is disconnected.

The boolean return value will be true if the database was already running or successfully started. Error information will be returned in the SQLCA.


db_stop_database function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Connection and engine management functions

db_stop_database function

Prototype

void db_stop_database( struct sqlca * sqlca,

 char * parms );

Description

Stop a database identified by DatabaseName on an engine or network server identified by EngineName. If EngineName is not specified, the default engine or network server will be used.

By default, this function will not stop a database that has existing connections. If Unconditional is yes, the database will be stopped regardless of existing connections.


db_stop_engine function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Connection and engine management functions

db_stop_engine function

Prototype

void db_stop_engine( struct sqlca * sqlca,

 char * parms );

Terminates execution of the database engine or SQL Anywhere Client (DBCLIENT.EXE). This function will do the following steps:

Description

♦	Look for a local database engine that has a name that matches the EngineName parameter. If no EngineName is specified, look for the default local database engine.

♦	Look for the SQL Anywhere Client.

♦	If no matching engine or SQL Anywhere Client is found, this function fails.

♦	Send a request to the engine to tell it to checkpoint and shut down all databases.

♦	Unload the database engine or SQL Anywhere Client.

By default, this function will not stop a database engine or SQL Anywhere Client that has existing connections. If Unconditional is yes, the database engine or SQL Anywhere Client will be stopped regardless of existing connections.

This function can be used directly from a C program instead of spawning DBSTOP.


db_find_engine function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Connection and engine management functions

db_find_engine function

Prototype

unsigned short db_find_engine( struct sqlca *sqlca, char *name );

Description

Returns an unsigned short value indicating status information about the database engine whose name is name. If neither an engine nor multiuser server can be found with the specified name, the return value will be 0. A non-zero value indicates that the engine or client is currently running. Each bit in the return value conveys some information. Constants representing the bits for the various pieces of information are defined in the SQLDEF.H header file (see "SQLDEF.H header file"). If a null pointer is specified for name, then information is returned about the default database environment.


db_build_parms function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Connection and engine management functions

db_build_parms function

Prototype

struct a_dblib_info *db_build_parms( struct sqlca *sqlca, char *connectstr, char *startstr );

Description

Historical. See db_string_connect.


db_destroy_parms function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Connection and engine management functions

db_destroy_parms function

Prototype

void db_destroy_parms( struct sqlca *sqlca, a_dblib_info *parms );

Description

Historical. See db_string_connect.


db_free_parms function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Connection and engine management functions

db_free_parms function

Prototype

void db_free_parms( a_dblib_info *parms );

Description

Historical. See db_string_connect.


db_parms_connect function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Connection and engine management functions

db_parms_connect function

Prototype

unsigned db_parms_connect( struct sqlca *sqlca, a_dblib_info *info );

Description

Historical. See db_string_connect.


db_parms_disconnect function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Connection and engine management functions

db_parms_disconnect function

Prototype

void db_parms_disconnect( struct sqlca *sqlca, a_dblib_info *info );

Description

Historical. See db_string_disconnect.


db_start function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Connection and engine management functions

db_start function

Prototype

unsigned db_start( struct sqlca *sqlca, a_dblib_info *info );

Description

Historical. See db_start_engine and db_start_database.


db_stop function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Connection and engine management functions

db_stop function

Prototype

void db_stop( struct sqlca *sqlca, char *name, short unconditional );

Description

Historical. See db_stop_engine and db_stop_database.


SQLDA management functions
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

SQLDA management functions

The following functions are used to manage SQL Descriptor Areas (SQLDAs). "The SQL descriptor area (SQLDA)" describes the SQLDA structure in detail.

 alloc_sqlda_noind function

 alloc_sqlda function

 fill_sqlda function

 sqlda_string_length function

 sqlda_storage function

 fill_s_sqlda function

 free_filled_sqlda function

 free_sqlda_noind function

 free_sqlda function


alloc_sqlda_noind function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

SQLDA management functions

alloc_sqlda_noind function

Prototype

struct sqlda *alloc_sqlda_noind( unsigned numvar );

Description

Allocates an SQLDA with descriptors for numvar variables. The sqln field of the SQLDA will be initialized to numvar. Space is not allocated for indicator variables; the indicator pointers are set to the null pointer. A null pointer will be returned if memory cannot be allocated.


alloc_sqlda function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

SQLDA management functions

alloc_sqlda function

Prototype

struct sqlda *alloc_sqlda( unsigned numvar );

Description

Allocates an SQLDA with descriptors for numvar variables. The sqln field of the SQLDA will be 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 will be returned if memory cannot be allocated.


fill_sqlda function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

SQLDA management functions

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.


sqlda_string_length function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

SQLDA management functions

sqlda_string_length function

Prototype

unsigned long sqlda_string_length( struct sqlda *sqlda, int varno );

Description

Returns the length of a C string (type DT_STRING) required to hold the variable sqlda->sqlvar[varno] (no matter what its type is).


sqlda_storage function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

SQLDA management functions

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].


fill_s_sqlda function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

SQLDA management functions

fill_s_sqlda function

Prototype

struct sqlda *fill_s_sqlda( struct sqlda *sqlda, unsigned int maxlen );

Description

Much the same as fill_sqlda except that it changes all the data types in sqlda to type DT_STRING (see "SQLDEF.H header file"). Enough space is allocated for the strings 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.


free_filled_sqlda function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

SQLDA management functions

free_filled_sqlda function

Prototype

void free_filled_sqlda( struct sqlda *sqlda );

Description

Free all space allocated to this sqlda including the memory allocated to each sqldata pointer. Any null pointer will not be freed. The indicator variable space is also freed as allocated in fill_sqlda.


free_sqlda_noind function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

SQLDA management functions

free_sqlda_noind function

Prototype

void free_sqlda_noind( struct sqlda *sqlda );

Description

Free the space allocated to this sqlda but do not free the memory referenced by each sqldata pointer. The indicator variable pointers are ignored.


free_sqlda function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

SQLDA management functions

free_sqlda function

Prototype

void free_sqlda( struct sqlda *sqlda );

Description

Free the space allocated to this sqlda but do not free the memory referenced by each sqldata pointer. The indicator variable space is also freed as allocated in fill_sqlda.


Backup functions
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Backup functions

The db_backup function provides support for online backup. The SQL Anywhere 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 SQL Anywhere backup utility.

Every database contains one or more files. Normally, a database contains two files, the main database file and the transaction log. Each file is divided up into fixed size pages, and the size of these pages is specified when the database was created. Backup works by opening a file, and then making a copy of each page in the file. Backup performs a checkpoint on startup. The database file(s) is backed up as of this checkpoint. Any changes made while the backup is running are recorded in the transaction log and will be backed up with the transaction log. This is why you always backup the transaction log last.

Authorization

You must be connected to a user ID with DBA authority or REMOTE DBA authority (SQL Remote) to use the backup functions.

 db_backup function

 db_delete_file function


db_backup function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Backup functions

db_backup function

Prototype

void db_backup( struct sqlca * sqlca, int op, int file_num, unsigned long page_num, struct sqlda * sqlda);

Authorization

Must be connected to a user ID with DBA authority or REMOTE DBA authority (SQL Remote).

Description

The action performed by the db_backup function 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 engine. 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 will be SQLE_BACKUP_NOT_STARTED. Otherwise, the SQLCOUNT field of the sqlca will be 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 main 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 will be 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 will be set to SQLE_NOTFOUND. The sqlda descriptor should be set up with one variable of type DT_BINARY pointing to a buffer that is large enough to hold binary data of the size returned in SQLCOUNT on the call to db_backup with the DB_BACKUP_START operation. (Note that 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.)

Although the DBBACKUP program reads the pages sequentially in the database file, the pages could be read in any order.

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  engine will rename the transaction log and start a new one.  If the database engine is unable to rename the log at the  current time (there are incomplete transactions), you will  get the SQLE_BACKUP_CANNOT_RENAME_LOG_YET error. In this case,  don't 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. Note that 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 will be  returned in the sqlerrmc field of the SQLCA.

♦	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 algorithm used by the DBBACKUP program is as follows. 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_delete_file function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Backup functions

db_delete_file function

Prototype

void db_delete_file( struct 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 engine to delete filename. This can be used after backing up and renaming the transaction log (see DB_BACKUP_READ_RENAME_LOG above) to delete the old transaction log. Note that this request will work both with the single-user engine and the multiuser server. You must be connected to a userid with DBA authority.


Other functions
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Other functions

 sql_needs_quotes function

 sqlerror_message function


sql_needs_quotes function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Other functions

sql_needs_quotes function

Prototype

unsigned int sql_needs_quotes( struct sqlca *sqlca, char *str );

Description

Returns a boolean indicating whether or not the string str requires double quotes around it when it is used as a SQL identifier. This function actually formulates a request to the database engine to determine if quotes are needed.


sqlerror_message function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Other functions

sqlerror_message function

Prototype

char *sqlerror_message( struct sqlca *sqlca, char * buffer, int max );

Description

Return a pointer to a string containing 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 will be placed in the buffer supplied truncated to length max if necessary.


Aborting a request
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Aborting a request

 db_abort_request function

 db_cancel_request function

 db_is_working function

 db_working function


db_abort_request function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Aborting a request

db_abort_request function

Prototype

int db_abort_request( void );

Description

Historical. See db_cancel_request.


db_cancel_request function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Aborting a request

db_cancel_request function

Prototype

int db_cancel_request( struct sqlca *sqlca );

Description

Abort the currently active database engine request. This function will check to make sure a database engine request is active before sending the abort request. The return value indicates whether or not an abort request was sent; in other words, whether or not a database request was active. A non-zero return value does not mean that the request was aborted. There are a few critical timing cases where the abort request and the response from the database or server "cross". In these cases, the abort simply has no effect.

Note that db_cancel_request can be called asynchronously (from an interrupt handler, a Window procedure in Windows, or from another OS/2 or Windows NT thread). 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.

In DOS, the default CTRL+BREAK handling mechanism in the database interface library calls this routine when a CTRL+BREAK is detected.


db_is_working function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Aborting a request

db_is_working function

Prototype

unsigned db_is_working( struct 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 (from an interrupt handler, a Window procedure in Windows, or from another OS/2 or Windows NT thread). 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_working function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Aborting a request

db_working function

Prototype

unsigned db_working( void );

Description

Historical. See db_is_working.


Windows 3.x request management
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Windows 3.x request management

This section does not apply to Windows NT or Windows 95.

You may have noticed when using ISQL under Windows that the Windows system is still active while ISQL is waiting for a response from the database. This is not the default behavior of the interface DLL. Default behavior puts the hour glass cursor on the screen and forces the user to wait for completion of the request.

The proper way to provide this active behavior for an application would be through the use of asynchronous database requests. The current release of SQL Anywhere does not support asynchronous requests but you can achieve application activity in Windows while a database request is in progress by providing a callback function. The key difference is that 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.

This callback function in your application will be called repeatedly while the database engine or SQL Anywhere Client is busy processing a request. You can then process Windows messages by calling GetMessage or PeekMessage. (These function calls allow Windows to be active.) The DBL50 DLL will continually call this function until the response from the database engine is received.

Response in Windows message—The response from the engine or SQL Anywhere Client comes to your application via a Windows message. You must either dispatch this message (the interface DLL will receive the message), or you must call the db_process_message function with each message you receive while in this callback function. The function will return TRUE if the message was the response; otherwise you can process the message normally by dispatching it.

The following function is used to register your application callback functions:

 db_register_a_callback function

 db_process_a_message function


db_register_a_callback function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Windows 3.x request management

db_register_a_callback function

Prototype

void db_register_a_callback( struct sqlca *sqlca, a_db_callback_index index, FARPROC callback );

Description

This function is used to register Windows callback functions. To remove a callback, pass a null pointer as the callback function. Following is a list of the allowable values for index and the appropriate function prototype. Note that you should call MakeProcInstance with your function address and pass that to the db_register_callback function.

If you don't register any callback functions, then the default action is to do nothing. Your application will block waiting for the database response and Windows will change the cursor to an hour glass.

The following values are allowed for the index parameter:

♦	DB_CALLBACK_START   void FAR PASCAL db_start_request( struct sqlca *sqlca );

This function is called just before a database request is sent to the engine or SQL Anywhere Client.

♦	DB_CALLBACK_FINISH   void FAR PASCAL db_finish_request( struct sqlca *sqlca );

This function is called after the response to a database request has been received by the interface DLL.

♦	DB_CALLBACK_WAIT   void FAR PASCAL db_wait_request( struct sqlca *sqlca );

This function is called repeatedly by the interface DLL while the database engine or SQL Anywhere Client is busy processing your database request.

The following is a sample DB_CALLBACK_WAIT callback function:

void FAR PASCAL db_wait_request( struct sqlca *sqlca )

{ MSG msg

   f( GetMessage( &msg, NULL, 0, 0 ) ) {

      ( !db_process_a_message( sqlca, &msg ) ) {

         if( !TranslateAccelerator( hWnd, hAccel, &msg ) ) {

         TranslateMessage( &msg )

         DispatchMessage( &msg )

         }

      }

   }

}


db_process_a_message function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Windows 3.x request management

db_process_a_message function

Prototype

int db_process_a_message( struct sqlca *sqlca, MSG *msg );

Description

This function is called from within your db_wait_request callback function to determine if the message you received from Windows was in fact the response to the active database request. The return value will be TRUE if msg is the response. Simply return from the callback function and the embedded SQL library DLL will process the response by returning to the call that generated the original request.


Multiple SQLCA management
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Multiple SQLCA management

 db_set_sqlca function

 db_get_sqlca function


db_set_sqlca function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Multiple SQLCA management

db_set_sqlca function

Prototype

void db_set_sqlca( struct sqlca *sqlca );

Description

Historical (DOS and Windows). See "SET SQLCA statement".


db_get_sqlca function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Multiple SQLCA management

db_get_sqlca function

Prototype

struct sqlca *db_get_sqlca( void );

Description

Historical (DOS and Windows). See "SET SQLCA statement".


Memory allocation in DOS and QNX
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Memory allocation in DOS and QNX

In DOS and QNX, all database library functions use the following functions to allocate and free memory. On all other operating systems, the interface DLL manages its own memory.

These functions are in a module by themselves and simply call the normal C memory functions: malloc, realloc and free. In DOS and QNX, you can use different memory management functions by redefining DBAlloc, DBRealloc and DBFree in your application code (all three must be redefined together). Refer to the documentation for your C compiler and linker to see how to force the new definitions of these functions to be used instead of the versions supplied in the database library. Usually, this is a matter of naming your replacement file before the library in the linker command file.

 DBAlloc function

 DBRealloc function

 DBFree function


DBAlloc function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Memory allocation in DOS and QNX

DBAlloc function

Prototype

void *DBAlloc( unsigned int size );

Description

Allocates a piece of memory size bytes long and returns a pointer to it. This function is called by the interface library in order to dynamically allocate memory. The default routine in the library calls malloc.


DBRealloc function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Memory allocation in DOS and QNX

DBRealloc function

Prototype

void *DBRealloc( void *ptr, unsigned int size );

Description

Reallocates the piece of memory pointed to by ptr to be size bytes long and returns a pointer to it. The contents of the original piece are present in the new piece of memory. This function is called by the interface library in order to dynamically reallocate memory. The default routine in the library calls realloc.


DBFree function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

Memory allocation in DOS and QNX

DBFree function

Prototype

void DBFree( void *ptr );

Description

Frees the dynamic memory piece pointed to by ptr. This function is called by the interface library in order to dynamically free a piece of memory. The default routine in the library calls free.


DOS interrupt processing and request management
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

DOS interrupt processing and request management

The database interface library contains default handling mechanisms for CTRL+BREAK and the CRITICAL DEVICE ERROR ("Abort,Retry,Ignore?" errors) in DOS. These handlers modify the default behavior as follows:

♦	Ctrl+Break   DOS's default handling for the break key is to terminate the active program. The default database library handler modifies the behavior so that if the database engine is running when CTRL+BREAK is pressed, the active request will be terminated, however, no programs will be terminated.

♦	critical device error   DOS normally prompts the user with "Abort,Retry,Ignore?" when a critical error is detected. The default handler automatically fails the device request. The database engine will detect the error and enter a state where it will not process any further requests. This prevents further problems from occurring. You should stop the database engine, correct any device problems and restart the database.

By default, the interrupt handlers are installed before each request to the database engine and deinstalled after each request is completed. Both the installation mechanism and the function performed by the interrupt handler can be modified. Be cautious though, noting the above mentioned DOS default behavior for CTRL+BREAK and critical errors. In particular, the default behavior for CTRL+BREAK is not appropriate; terminating the database engine in that way will cause your machine to hang up.

The functions db_sending_request and db_finished_request described below are called before and after a database engine request. If you wish to provide different handlers for the CTRL+BREAK or critical device error interrupts, you should replace these functions with ones of your own.

You may want to catch these interrupts once when your application starts up by providing your own handlers for the interrupts. This will eliminate the overhead of catching the interrupts on every database request. This is the way that ISQL handles the CTRL+BREAK and critical error interrupts.

 db_sending_request function

 db_finished_request function

 db_catch_break function

 db_release_break function

 db_break_handler function

 db_catch_critical function

 db_release_critical function

  function


db_sending_request function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

DOS interrupt processing and request management

db_sending_request function

Prototype

void db_sending_request( void );

Description

This function is called by the database library before a request is sent to the engine. The default action provided by the version of this routine in the interface library is:

db_catch_break( db_break_handler );

db_catch_critical( db_critical_handler );

To modify CTRL+BREAK or critical error handling, provide your own version of this function.


db_finished_request function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

DOS interrupt processing and request management

db_finished_request function

Prototype

void db_finished_request( void );

Description

This function is called by the database library after a request to the engine is completed. The default action provided by the version of this routine in the interface library is:

db_release_critical();

db_release_break();

To modify CTRL+BREAK or critical error handling, provide your own version of this function.

The following functions are used by db_sending_request() and db_finished_request() in catching and processing the CTRL+BREAK and critical device error interrupts. They can also be used by your replacements for these routines.


db_catch_break function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

DOS interrupt processing and request management

db_catch_break function

Prototype

void db_catch_break( void (interrupt far *rtn)( void ) );

Description

This function installs rtn as the break handling routine. It will save the previous break handler so that it can be restored by db_release_break().


db_release_break function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

DOS interrupt processing and request management

db_release_break function

Prototype

void db_release_break( void );

Description

This function deinstalls the break handler previously installed by db_catch_break and reinstalls the old break handler. Note that if some other program has replaced the break handler since your call to db_catch_break, then that handler will get lost when the old break handler is reinstalled.


db_break_handler function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

DOS interrupt processing and request management

db_break_handler function

Prototype

void interrupt db_break_handler( void );

Description

This is the default break handler for the database interface library. It calls db_cancel_request to abort the active database request.


db_catch_critical function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

DOS interrupt processing and request management

db_catch_critical function

Prototype

void db_catch_critical( void (interrupt far *rtn)( void ) );

Description

This function installs rtn as the critical device error handling routine. It will save the previous handler so that it can be restored by db_release_critical().


db_release_critical function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

DOS interrupt processing and request management

db_release_critical function

Prototype

void db_release_critical( void );

Description

This function uninstalls the critical device error handler previously installed by db_catch_critical and reinstalls the old handler. Note that if some other program has replaced the critical error handler since your call to db_catch_critical, then that handler will get lost when the old critical error handler is reinstalled.


function
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Library functions

DOS interrupt processing and request management

 function

Prototype

void interrupt db_critical_handler( void );

Description

This is the default critical device error handler for the database interface library. The action specified in the library routine is to move a 3 into the AH register and issue an IRET instruction. This causes DOS to report a failure to the task that issued the I/O request. Note that by default, this handler is installed and deinstalled around each request to the database engine. Thus the task that issued the I/O request must have been the database engine. The engine expects to receive the failure status and will recover appropriately.


Interface library DLL dynamic loading
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Interface library DLL dynamic loading

The interface library DLL can be loaded dynamically without having to link against the import library for the DLL, using the ESQLDLL.C module in the SRC subdirectory of your installation directory. Using ESQLDLL.C is recommended as it is easier to use and more robust in its ability to locate the interface DLL.

 To use the dynamic loading feature:

1	Your program must call db_init_dll to load the DLL, and must call db_fini_dll to free the DLL.  db_init_dll must be called before any function in the database interface, and no function in the interface can be called after db_fini_dll.

  For more details on db_init_dll and 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	You must ensure that a SQL OS macro is defined when compiling ESQLDLL.C.  The header file SQLCA.H, which is included by this file, attempts to determine the appropriate macro and defines 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 by using a compiler option.

Macro	Platforms
_SQL_OS_WINNT	Windows 95 and Windows NT
_SQL_OS_WINDOWS	Windows 3.x
_SQL_OS_OS232	32-bit OS/2
4	Compile ESQLDLL.C.

5	Instead of linking against the imports library, link the object    module ESQLDLL.OBJ with your embedded SQL application objects.

Example

The following example illustrates how to use ESQLDLL.C and ESQLDLL.H.:

#include <stdio.h>

#include "esqldll.h"

EXEC SQL INCLUDE SQLCA;

#include "sqldef.h"

#include <windows.h>

EXEC SQL BEGIN DECLARE SECTION;

int            x;

a_sql_statement_number       stat1;

EXEC SQL END DECLARE SECTION;

#define TRUE 1

#define FALSE 0

void printSQLError( void )

{

   char      buffer[200];

   sqlerror_message( &sqlca, buffer, sizeof(buffer) );

   #ifdef _SQL_OS_WINDOWS

   printf( "Error %ld -- %Fs\n", SQLCODE, buffer );

   #else

   printf( "Error %ld -- %s\n", SQLCODE, buffer );

   #endif

}

char *dllpaths[] = { "s:\\jasonhi\\",

          NULL };

#include <windows.h>

int main( void )

{

   struct sqlda _fd_ *   sqlda1;

   int         result;

   char      string[200];

   printf( "Initing DLL\n" );

   result = db_init_dll( dllpaths );

   switch( result ) {

   case ESQLDLL_OK:

      printf("OK\n");

      break;

      case ESQLDLL_DLL_NOT_FOUND:

      printf("DLL NOT FOUND\n");

      return( 10 );

   case ESQLDLL_WRONG_VERSION:

      printf("WRONG VERSION\n");

      return( 10 );

   }

   if( !db_init( &sqlca ) ) {

      printf("db_init failed.\n");

      db_fini_dll();

   return( 10 );

   }

   #ifdef _SQL_OS_WINNT

   result = db_string_connect( &sqlca, "UID=dba;PWD=sql;DBF=d:\\sqlany50\\sample.db");

   #elif defined( _SQL_OS_WINDOWS )

   result = db_string_connect( &sqlca, "UID=dba;PWD=sql;DBF=c:\\wsql50\\sample.db");

   #elif defined( _SQL_OS_OS232 )

   result = db_string_connect( &sqlca, "UID=dba;PWD=sql;DBF=h:\\wsql50\\sample.db");

   #endif

   if( ! result ) {

      printf( "db_string_connect returned = %d\n", result );

   printSQLError();

   }

   sqlda1 = alloc_descriptor( sqlcaptr, 20 );

   EXEC SQL PREPARE :stat1 FROM

      'select * from employee

      WHERE empnum = 80921';

   if( SQLCODE != 0 ) {

      printSQLError();

   }

   EXEC SQL DECLARE curs CURSOR FOR :stat1;

   if( SQLCODE != 0 ) {

      printSQLError();

   }

   EXEC SQL OPEN curs;

   if( SQLCODE != 0 ) {

      printSQLError();

   }

   EXEC SQL DESCRIBE :stat1 INTO sqlda1;

   if( SQLCODE != 0 ) {

      printSQLError();

   }

   sqlda1->sqlvar[1].sqltype = 460;

   fill_sqlda( sqlda1 );

   EXEC SQL FETCH FIRST curs INTO DESCRIPTOR sqlda1;

   if( SQLCODE != 0 ) {

      printSQLError();

   }

   printf( "name = %Fs\n", (char _fd_ *)sqlda1->sqlvar[1].sqldata );

   x = sqlda1->sqld;

   printf( "COUNT = %d\n", x );

   free_filled_sqlda( sqlda1 );

   db_string_disconnect( &sqlca, "" );

   db_fini( &sqlca );

   db_fini_dll();

   return( 0 );

}


Embedded SQL commands
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Embedded SQL commands

EXEC SQL—ALL Embedded SQL statements must be preceded with EXEC SQL and end with a semicolon.

Embedded SQL commands are broken into two groups:

♦	Standard SQL commands that are part of the SQL language. These commands are further broken into two groups, the data manipulation commands and the data definition commands. They 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. All commands are described in detail in "Watcom-SQL Language Reference".

♦	Data Manipulation Commands:

Statement	Description
CALL	Invoke a database procedure
CHECKPOINT	Cause the database engine to write all modified information
COMMIT	Commit changes to the database
DELETE	Delete rows from a database table
INSERT	Insert rows into database tables
PREPARE TO COMMIT	First phase of two-phase commit
RELEASE SAVEPOINT	Release a savepoint
ROLLBACK	Undo changes to database
ROLLBACK TO SAVEPOINT	Undo changes to database
SAVEPOINT	Establish a savepoint within a transaction
SELECT	Retrieve information from the database
UPDATE	Update rows in the database.
♦	Data Definition Commands: :

Statement	Description
ALTER	Modify a database table definition
COMMENT ON	Fill in remarks column for tables and columns
CREATE	Create database objects
DROP	Remove objects from the database
GRANT	Create userids, grant privileges to users
REVOKE	Delete userids, revoke privileges from users
SET OPTION	Set database options
VALIDATE TABLE	Check validity of table contents and all indexes on table
In addition to the standard SQL data manipulation and data definition commands, there are several SQL commands that are specific to Embedded SQL and can only be used in a C program. These Embedded SQL commands are also described in "Watcom-SQL Language Reference".

♦	CLOSE   close a cursor

♦	CONNECT   connect to the database

♦	Declaration Section   declare host variables for database communication

♦	DECLARE   declare a cursor

♦	DELETE (positioned)    delete the row at the current position in a cursor

♦	DESCRIBE   describe the host variables for a particular SQL statement

♦	DISCONNECT   disconnect from database engine

♦	DROP STATEMENT   free resources used by a prepared statement

♦	EXECUTE   execute a particular SQL statement

♦	EXPLAIN   explain the optimization strategy for a particular cursor

♦	FETCH   fetch a row from a cursor

♦	GET OPTION   get the setting for a particular database option

♦	INCLUDE   include a file for SQL preprocessing

♦	OPEN   open a cursor

♦	PREPARE   prepare a particular SQL statement

♦	PUT   insert a row into a cursor

♦	SET CONNECTION   change active connection

♦	SET OPTION   change a database option value

♦	SET SQLCA   use an SQLCA other than the default global one

♦	UPDATE (positioned)    update the row at the current location of a cursor

♦	WHENEVER   specify actions to occur on errors in SQL statements


Database examples
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Database examples

Two embedded SQL examples are included with the SQL Anywhere installation. The static cursor Embedded SQL example, CUR.SQC, demonstrates the use of static SQL statements. The dynamic cursor Embedded SQL example, DCUR.SQC, demonstrates the use of dynamic SQL statements. In addition to these examples, you may find other programs and source files as part of the installation of SQL Anywhere which demonstrate features available for particular platforms.

 Building the examples

 Running the example programs

 Static cursor example

 Dynamic cursor example

 NT Service examples


Building the examples
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Database examples

Building the examples

All of the examples are installed as part of the SQL Anywhere installation. They are placed in the CXMP subdirectory of the SQL Anywhere installation directory (usually C:\SQLANY50). Under QNX, they are found in /usr/sqlany50/sample.

Along with the sample program is a batch file, MAKEALL.BAT, that can be used to compile the sample program for the various environments and compilers supported by SQL Anywhere. For OS/2 the command is MAKEALL.CMD. For QNX, use the shell script makeall. The format of the command is as follows:

makeall {Example} {Platform} {Compiler} [DOS Extender]

The first parameter is the name of the example program that you want to compile. It will be one of:

♦	cur   static cursor example

♦	dcur   dynamic cursor example

The second parameter is the platform in which the program will be run. The platform can be one of the following:

♦	DOS   compile for 16-bit DOS.

♦	DOS286   compile for 16-bit protected mode using Pharlap/286 DOS Extender.

♦	DOS32   compile for 32-bit Extended DOS. You must specify a DOS Extender.

♦	WINDOWS   compile for 16-bit Windows.

♦	WIN32   compile for 32-bit Windows using the Watcom C 32-bit Windows support.

♦	WINNT   compile for Windows NT.

♦	OS232   compile for 32-bit OS/2.

♦	NETWARE   compile for Netware NLM.

♦	QNX   compile for 16-bit or 32-bit QNX.

The third parameter is the compiler to use to compile the program. The compiler can be one of:

♦	WC   use Watcom C or Watcom C/32

♦	MC   use Microsoft C

♦	BC   use Borland C

♦	CS   use IBM C Set++

The fourth parameter is optional, and specifies the DOS Extender being used to run the program. This option only applies when the platform is DOS286 or DOS32. The DOS Extender can be one of:

♦	4G   Rational DOS/4GW

♦	P3   Pharlap/386

♦	P2   Pharlap/286


Running the example programs
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Database examples

Running the example programs

All example programs present a console-type user interface where it prompts you for a command. The various commands manipulate a database cursor and print the query results on the screen. Simply type the letter of the command you wish to perform. Some systems may require you to press ENTER after the letter. The commands are similar to the following depending on which program you run:

♦	p   print current page

♦	u   move up a page

♦	d   move down a page

♦	b   move to bottom page

♦	t   move to top page

♦	i   insert a row (DCUR only)

♦	n   new table (DCUR only)

♦	q   quit

♦	h   help (this list of commands)

Windows and Windows NT examples

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 attempt to mimic the console type interface of the DOS examples. As such, they do not repaint their Windows on WM_PAINT messages except to reprint the prompt.

To run these programs, execute them by selecting Run from the Program Manager File menu and typing:

c:\sqlany50\cxmp\curwin.exe

or create a Program Manager icon for them.


Static cursor example
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Database examples

Static cursor example

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 example") takes this first example and converts it to use dynamic SQL statements.

See "Database examples" for where the source code can be found and how to build this example program.

The C program with the Embedded SQL is shown below. The program looks much like a standard C program except there are Embedded SQL instructions that begin with EXEC SQL. In order to reduce the amount of code duplicated by the cur and dcur example programs (and the odbc example), 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 Windows and Windows NT. The example programs each supply the following three routines which are called from the mainlines.

♦	WSQLEX_Init   connect to the database and open the cursor

♦	WSQLEX_Process_Command   process commands from the user, manipulating the cursor as necessary.

♦	WSQLEX_Finish   close the cursor and disconnect from the database.

The function of the mainline is to:

♦	call the WSQLEX_Init routine

♦	loop getting commands from the user and calling WSQL_Process_Command until the user quits

♦	call the WSQLEX_Finish routine

Connecting to the database is accomplished with the Embedded SQL CONNECT command supplying the appropriate userid and password.

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 (end of cursor) and prints appropriate messages when they arise. Also, the SQL cursor is repositioned by this program to the row before the one that is displayed at the top of the current page of data.

The move, top and bottom routines use the appropriate format 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. In this case, this is accomplished with the ROLLBACK WORK statement followed by a DISCONNECT.

/* CUR.SQC      General SQL code for Cursex example (all platforms)

*/

#include <stdio.h>

#include <ctype.h>

EXEC SQL INCLUDE SQLCA;

#include "sqldef.h"

#include "example.h"

extern int              PageSize;

typedef struct a_student {

    unsigned long       studnum;

    char                name[ 41 ];

    char                sex[ 2 ];        /* M or F plus null char */

    char                birthdate[ 15 ];

} a_student;

static void printSQLError()

{

    char                buffer[ 200 ];

    Displaytext( 0, "SQL error -- %s\n",

        sqlerror_message( &sqlca, buffer, sizeof( buffer ) ) );

}

static int warning( char *msg )

{

    if( SQLCODE == SQLE_NOTFOUND ) {

        Displaytext( 2, "Not found - past count %ld -- %s\n",

                                                SQLCOUNT, msg );

    } else {

        Displaytext( 2, "Unexpected warning %ld -- %s\n",

                                                SQLCODE, msg );

    }

    return( TRUE );

}

EXEC SQL WHENEVER SQLERROR { printSQLError(); return( FALSE ); };

static int connect()

{

    EXEC SQL CONNECT "DBA" IDENTIFIED BY "SQL";

    return( TRUE );

    /* errors will return FALSE: - see WHENEVER above */

}

static int release()

{

    EXEC SQL ROLLBACK WORK;

    EXEC SQL DISCONNECT;

    db_fini( &sqlca );

    return( TRUE );

}

static int open_cursor()

{

    EXEC SQL DECLARE C1 CURSOR FOR

        SELECT studnum, initials || ' ' || surname, sex, birthdate

        FROM admin.student;

    EXEC SQL OPEN C1;

    return( TRUE );

}

static int close_cursor()

{

    EXEC SQL CLOSE C1;

    return( TRUE );

}

static int fetch_row(

    EXEC SQL BEGIN DECLARE SECTION;

    unsigned long       *studnum,

    char                *name,

    char                *sex,

    char                *birthdate

    EXEC SQL END DECLARE SECTION;

    )

{

    EXEC SQL FETCH RELATIVE 1 C1

             INTO :studnum, :name, :sex, :birthdate;

    if( SQLCODE ) {

        warning( "Fetching" );

        return( FALSE );

    } else {

        return( TRUE );

    }

}

static int move(

    EXEC SQL BEGIN DECLARE SECTION;

    int                 relpos

    EXEC SQL END DECLARE SECTION;

    )

{

    EXEC SQL FETCH RELATIVE :relpos C1;

    return( TRUE );

}

static int top()

{

    EXEC SQL FETCH ABSOLUTE 0 C1;

    return( TRUE );

}

static int bottom()

{

    EXEC SQL FETCH ABSOLUTE -1 C1;

    return( TRUE );

}

static void help()

{

    Displaytext( 0, "Cursex Demonstration Program Commands:\n" );

    Displaytext( 0, "p - Print current page\n" );

    Displaytext( 0, "u - Move up a page\n" );

    Displaytext( 0, "d - Move down a page\n" );

    Displaytext( 0, "b - Move to bottom page\n" );

    Displaytext( 0, "t - Move to top page\n" );

    Displaytext( 0, "q - Quit\n" );

    Displaytext( 0, "h - Help (this screen)\n" );

}

static void print()

{

    a_student           s;

    int                 i;

    int                 status;

    for( i = 0; i < PageSize; ) {

        ++i;

        status = fetch_row( &s.studnum, s.name, s.sex, s.birthdate );

        if( status ) {

            Displaytext( 0, "%6ld", s.studnum );

            Displaytext( 10, "%-30.30s", s.name );

            Displaytext( 30, "%-3.3s", s.sex );

            Displaytext( 40, "%-15.15s\n", s.birthdate );

        } else {

            break;

        }

    }

    move( -i );

}

extern int WSQLEX_Init()

{

    if( !db_init( &sqlca ) ) {

        Display_systemerror(

            "Unable to initialize database interface\n" );

        return( FALSE );

    }

    if( !db_find_engine( &sqlca, NULL ) ) {

        Display_systemerror( "Database Engine/Station not running" );

        return( FALSE );

    }

    if( !connect() ) {

        Display_systemerror( "Could not connect" );

        return( FALSE );

    }

    open_cursor();

    help();

    return( TRUE );

}

extern void WSQLEX_Process_Command( int selection )

{

    switch( tolower( selection ) ) {

        case 'p':       print();

                        break;

        case 'u':       move( -PageSize );

                        print();

                        break;

        case 'd':       move( PageSize );

                        print();

                        break;

        case 't':       top();

                        print();

                        break;

        case 'b':       bottom();

                        move( -PageSize );

                        print();

                        break;

        case 'h':       help();

                        break;

        default:        Displaytext( 0, "Invalid command, press 'h' for help\n" );

    }

}

extern int WSQLEX_Finish()

{

    close_cursor();

    release();

    return( TRUE );

}


Dynamic cursor example
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Database examples

Dynamic cursor example

This example demonstrates the use of cursors for a dynamic SQL SELECT statement. It is a slight modification of the previous example. If you have not yet looked at "Static cursor example" it would be helpful to do so before looking at this example.

See "Database examples" for where the source code can be found and how to build this example program.

The dcur program allows the user to specify the table he wishes to look at with the 'n' command. The program then presents as much information from that table as will fit on the screen. The SQL SELECT statement is built up in a program array using the C library function rintf.

When this program is run, it prompts for a connection string of the form:

uid=dba;pwd=sql;dbf=c:\sqlany50\sademo.db

The C program with the Embedded SQL is shown below. The program looks much like the previous example with the exception of the connect, open_cursor and print functions.

The connect function uses the Embedded SQL interface functions db_string_connect to connect to the database. This function provides the extra functionality to support the connection string used to connect to the database.

The open_cursor routine first builds the select statement:

SELECT * FROM tablename

where tablename is a parameter passed in 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 for 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, then the actual size of the select list returned by the database engine is used to allocate an SQLDA of the right size. The SQLDA structure is then filled with buffers to hold strings representing the results of the query. Note that the fill_s_sqlda routine converts all data types in the SQLDA to DT_STRING (see "SQLDEF.H header file") 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.

/* DCUR.SQC     General SQL code for Dcursex example (all platforms)

*/

#include <stdio.h>

#include <ctype.h>

#include <string.h>

#include <stdlib.h>

EXEC SQL INCLUDE SQLCA;

EXEC SQL INCLUDE SQLDA;

#include "sqldef.h"

#include "example.h"

#define MAX_COL_WIDTH   50

extern int              PageSize;

char                    TableName[MAX_TABLE_NAME];

SQLDA                   _fd_ *SqlDA;

#ifdef _SQL_OS_NETWARE

    #define Stringncopy(x,y,z)      strncpy(x,y,z)

    #define Stringcat(x,y)          strcat(x,y)

#else

    #ifdef __SMALLDATA__

        #define Stringncopy(x,y,z)    _fstrncpy(x,y,z)

        #define Stringcat(x,y)        _fstrcat(x,y)

    #else

        #define Stringncopy(x,y,z)    strncpy(x,y,z)

        #define Stringcat(x,y)        strcat(x,y)

    #endif

#endif

EXEC SQL BEGIN DECLARE SECTION;

char                    CursName[ 20 ];

EXEC SQL END DECLARE SECTION;

static void printSQLError()

{

    char                buffer[ 200 ];

    Displaytext( 0, "SQL error -- %s\n",

        sqlerror_message( &sqlca, buffer, sizeof( buffer ) ) );

}

static int warning( char *msg )

{

    if( SQLCODE == SQLE_NOTFOUND ) {

        if( SQLCOUNT >= 0 ) {

            Displaytext( 0, "Not found - past bottom of table\n" );

        } else {

            Displaytext( 0, "Not found - past top of table\n" );

        }

    } else {

        Displaytext( 0,

            "Unexpected warning %ld -- %s\n", SQLCODE, msg );

    }

    return( TRUE );

}

EXEC SQL WHENEVER SQLERROR { printSQLError(); return( FALSE ); };

static int open_cursor()

{

    EXEC SQL BEGIN DECLARE SECTION;

    char                    buff[ 100 ];

    a_sql_statement_number  stat;

    EXEC SQL END DECLARE SECTION;

    int                 n;

    sprintf( buff, "select * from %s", TableName );

    /* Note that database fills in statement number on prepare */

    EXEC SQL PREPARE :stat FROM :buff;

    /* Note that we must initialize the cursor name */

    strcpy( CursName, "table_cursor" );

    EXEC SQL DECLARE :CursName CURSOR FOR :stat;

    EXEC SQL OPEN :CursName;

    SqlDA = alloc_sqlda( 3 );

    EXEC SQL DESCRIBE :stat INTO SqlDA;

    if( SqlDA->sqld > SqlDA->sqln ) {

        n = SqlDA->sqld;

        free_sqlda( SqlDA );

        SqlDA = alloc_sqlda( n );

        EXEC SQL DESCRIBE :stat INTO SqlDA;

    }

    fill_s_sqlda( SqlDA, 1000 );

    return( TRUE );

}

static int close_cursor()

{

    EXEC SQL CLOSE :CursName;

    free_filled_sqlda( SqlDA );

    SqlDA = NULL;

    return( TRUE );

}

static int fetch_row()

{

    EXEC SQL FETCH RELATIVE 1 :CursName USING DESCRIPTOR SqlDA;

    if( SQLCODE < 0  ||  SQLCODE == SQLE_NOTFOUND ) {

        warning( "Fetching" );

        return( FALSE );

    } else if( SQLCODE != 0 ) {

        warning( "Fetching" );

        return( TRUE );

    } else {

        return( TRUE );

    }

}

static int move(

    EXEC SQL BEGIN DECLARE SECTION;

    int                 relpos

    EXEC SQL END DECLARE SECTION;

    )

{

    EXEC SQL FETCH RELATIVE :relpos :CursName;

    if( SQLCODE == SQLE_NOTFOUND && SQLCOUNT == 0 ) {

    } else if( SQLCODE ) {

        warning( "Moving" );

        return( FALSE );

    }

    return( TRUE );

}

static int top()

{

    EXEC SQL FETCH ABSOLUTE 0 :CursName;

    return( TRUE );

}

static int bottom()

{

    EXEC SQL FETCH ABSOLUTE -1 :CursName;

    return( TRUE );

}

static void help()

{

    Displaytext( 0, "DCursex Demonstration Program Commands:\n" );

    Displaytext( 0, "p - Print current page\n" );

    Displaytext( 0, "u - Move up a page\n" );

    Displaytext( 0, "d - Move down a page\n" );

    Displaytext( 0, "b - Move to bottom page\n" );

    Displaytext( 0, "t - Move to top page\n" );

    Displaytext( 0, "i - Insert a new row\n" );

    Displaytext( 0, "n - New table\n" );

    Displaytext( 0, "q - Quit\n" );

    Displaytext( 0, "h - Help (this screen)\n" );

}

static int col_width( SQLDA _fd_ *da, int col )

{

    int                 col_name_len;

    int                 data_len;

    SQLDA_VARIABLE      _fd_ *sqlvar;

    sqlvar = &da->sqlvar[ col ];

    col_name_len = sqlvar->sqlname.length;

    data_len = sqlvar->sqllen;

    if( data_len > col_name_len ) {

        col_name_len = data_len;

    }

    if( strlen( NULL_TEXT ) > col_name_len ) {

        col_name_len = strlen( NULL_TEXT );

    }

    if( col_name_len > MAX_COL_WIDTH ) {

        return( MAX_COL_WIDTH );

    }

    return( col_name_len );

}

static void print_headings( SQLDA _fd_ *da )

{

    int                 i;

    int                 width;

    int                 total;

    char                colname[ SQL_MAX_NAME_LEN + 1 ];

    char _fd_           *sqlname;

    total = 0;

    for( i = 0; i < da->sqld; ++i ) {

        width = col_width( da, i );

        sqlname = da->sqlvar[ i ].sqlname.data;

        Stringncopy( colname, sqlname,

            da->sqlvar[ i ].sqlname.length );

        colname[ da->sqlvar[ i ].sqlname.length ] = '\0';

        Displaytext( total, "%-*.*s", width, width, colname );

        total += width+1;

    }

    Displaytext( 0, "\n" );

}

static void print_data( SQLDA _fd_ *da )

{

    int                 i;

    int                 width;

    int                 total;

    SQLDA_VARIABLE _fd_ *sqlvar;

    char _sqldafar      *data;

    total = 0;

    for( i = 0; i < da->sqld; ++i ) {

        width = col_width( da, i );

        sqlvar = &da->sqlvar[ i ];

        if( *( sqlvar->sqlind ) < 0 ) {

            data = NULL_TEXT;

        } else {

            data = (char _sqldafar *)sqlvar->sqldata;

        }

        #if _sqlfar_isfar

            Displaytext( total, "%-*.*Fs", width, width,

                (char far *)data );

        #else

            Displaytext( total, "%-*.*s", width, width, data );

        #endif

        total += width+1;

    }

    Displaytext( 0, "\n" );

}

static void print()

{

    int                 i;

    if( SqlDA == NULL ) {

        Displaytext( 0, "*** Error: Cursor not open\n" );

        return;

    }

    print_headings( SqlDA );

    for( i = 0; i < PageSize; ) {

        ++i;

        if( fetch_row() ) {

            print_data( SqlDA );

        } else {

            break;

        }

    }

    move( -i );

}

static int insert()

{

    char        prompt[ 80 ];

    char *      tempptr;

    int         templen;

    int         i;

    for( i = 0; i < SqlDA->sqld; i++ ) {

        strcpy( prompt, "Enter a value for '" );

        Stringcat( prompt, SqlDA->sqlvar[i].sqlname.data);

        strcat( prompt, "'" );

        tempptr = (char *) SqlDA->sqlvar[i].sqldata;

        templen = SqlDA->sqlvar[i].sqllen;

        Getvalue( prompt, tempptr, templen );

        if( strlen( (char *)SqlDA->sqlvar[i].sqldata ) == 0

            && (SqlDA->sqlvar[i].sqltype & DT_NULLS_ALLOWED) != 0 ) {

            *SqlDA->sqlvar[i].sqlind = -1;

        } else {

            *SqlDA->sqlvar[i].sqlind = 0;

        }

    }

    EXEC SQL PUT :CursName USING DESCRIPTOR SqlDA;

    return( TRUE );

}

extern int WSQLEX_Init()

{

    char                parmstr[ 251 ];

    if( !db_init( &sqlca ) ) {

        Display_systemerror(

            "Unable to initialize database interface\n" );

        return( FALSE );

    }

    Getvalue( "Enter connection string", parmstr, 250 );

    if( strlen( parmstr ) == 0 ) {

        strcpy( parmstr,

            "UID=dba;PWD=sql;DBF=c:\\wsql\sample.db;ENG=sample" );

    }

    db_string_connect( &sqlca, parmstr );

    if( SQLCODE != SQLE_NOERROR ) {

        printSQLError();

        db_fini( &sqlca );

        return( FALSE );

    }

    Getvalue( "Enter table name", TableName, MAX_TABLE_NAME );

    open_cursor();

    help();

    return( TRUE );

}

extern void WSQLEX_Process_Command( int selection )

{

    switch( tolower( selection ) ) {

        case 'p':       print();

                        break;

        case 'u':       move( -PageSize );

                        print();

                        break;

        case 'd':       move( PageSize );

                        print();

                        break;

        case 't':       top();

                        print();

                        break;

        case 'b':       bottom();

                        move( -PageSize );

                        print();

                        break;

        case 'h':       help();

                        break;

        case 'n':       close_cursor();

                        Getvalue( "Enter table name",

                            TableName, MAX_TABLE_NAME );

                        open_cursor();

                        break;

        case 'i':       insert();

                        break;

        default:        Displaytext( 0,

                            "Invalid command, press 'h' for help\n" );

    }

}

extern int WSQLEX_Finish()

{

    close_cursor();

    EXEC SQL ROLLBACK WORK;

    EXEC SQL DISCONNECT;

    db_fini( &sqlca );

    return( TRUE );

}


NT Service examples
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

Database examples

NT Service examples

The example programs CUR.SQC and DCUR.SQC, when compiled for Windows NT, run optionally as services.

The two files containing the example code for NT services are the source file NTSVC.C and the header file NTSVC.H.  The code allows the linked executable to be run as either a regular executable or as an NT service.

 To run one of the compiled examples as an NT service:

1	Start the SQL Anywhere Service Manager.

2	Click New.  The Service Type window is displayed.

3	Click Sample Application, and click OK. The Edit SQL Anywhere Service Configuration window is displayed.

4	Enter a service name.

5	Click Path, and select the sample program (CURWNT.EXE or DCURWNT.EXE) from the CXMP subdirectory of the installation directory.

6	Click OK to install the service.

7	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++ 2.0 compiler.


SQLDEF.H header file
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 33. The Embedded SQL Interface

SQLDEF.H header file

/*****************************************************

Copyright (C) 1988-1993, by WATCOM International Corp.

All rights reserved. No part of this software may be

reproduced in any form or by any means - graphic,

electronic or mechanical, including photocopying,

recording, taping or information storage and retrieval

systems - except with the written permission of

WATCOM International Corp.

*****************************************************/

#ifndef II_SQLDEF

#define II_SQLDEF

#include "sqlca.h"

#include "sqlda.h"

#include "sqlerr.h"

#include "sqlstate.h"

/********************************************/

/* general definition of database constants */

/********************************************/

#define DB_MAX_IDENTIFIER_LEN   128

/**************************************************/

/* definitions for connection parms to dblib      */

/*   - used in functions: db_build_parms          */

/*                        db_free_parms           */

/*                        db_start                */

/*                        db_parm_connect         */

/**************************************************/

typedef struct a_dblib_info {

    char                _sqlfar *userid;

    char                _sqlfar *password;

    char                _sqlfar *database_name;

    char                _sqlfar *connection_name;

    char                _sqlfar *dbstartcommline;

} a_dblib_info;

/**************************************************/

/* constants for return values of DOS executables */

/**************************************************/

typedef short int an_exit_code;

#define EXIT_OKAY                   0   /* everything is okay */

#define EXIT_FAIL                   1   /* general failure */

#define EXIT_BAD_DATA               2   /* invalid file format, etc.*/

#define EXIT_FILE_ERROR             3   /* file not found, */

                                        /* unable to open, etc. */

#define EXIT_OUT_OF_MEMORY          4   /* out of memory */

#define EXIT_BREAK                  5   /* terminated by user */

#define EXIT_COMMUNICATIONS_FAIL    6   /* failed communications */

#define EXIT_MISSING_DATABASE       7   /* missing required db name */

#define EXIT_PROTOCOL_MISMATCH      8   /* client/server protocol */

                                        /* mismatch */

#define EXIT_UNABLE_TO_CONNECT      9   /* unable to connect to db */

#define EXIT_ENGINE_NOT_RUNNING     10  /* database not running */

#define EXIT_SERVER_NOT_FOUND       11  /* server not running */

#define EXIT_TIMEOUT                254 /* stop time reached */

#define EXIT_USAGE                  255 /* invalid command line */

/************************************************/

/* constants for return value of db_find_engine */

/************************************************/

#define DB_ENGINE               0x0001

#define DB_CLIENT               0x0002

#define DB_CAN_MULTI_DB_NAME    0x0004

#define DB_DATABASE_SPECIFIED   0x0008

#define DB_ACTIVE_CONNECTION    0x0010

#define DB_CONNECTION_DIRTY     0x0020

#define DB_CAN_MULTI_CONNECT    0x0040

#define DB_NO_DATABASES         0x0080

/**********************************/

/* host language type definitions */

/**********************************/

typedef unsigned short  a_sql_data_type;

#define DT_TYPES        0x03fe

#define DT_FLAGS        0xfc01

#define DT_NULLS_ALLOWED        0x0001

/* The following flags are used in the */

/* indicator variable on a describe */

#define DT_UPDATABLE            0x2000

#define DT_DESCRIBE_INPUT       0x1000

#define DT_PROCEDURE_IN         0x4000

#define DT_PROCEDURE_OUT        0x8000

#define DT_NOTYPE       0

#define DT_SMALLINT     500

#define DT_INT          496

#define DT_DECIMAL      484

#define DT_FLOAT        482

#define DT_DOUBLE       480

#define DT_DATE         384

#define DT_STRING       460

#define DT_FIXCHAR      452

#define DT_VARCHAR      448

#define DT_LONGVARCHAR  456

#define DT_TIME         388

#define DT_TIMESTAMP    392

#define DT_TIMESTAMP_STRUCT 390

#define DT_BINARY       524

#define DT_LONGBINARY   528

#define DT_VARIABLE     600

/**************************/

/* Backup operation types */

/**************************/

#define DB_BACKUP_START             1

#define DB_BACKUP_OPEN_FILE         2

#define DB_BACKUP_READ_PAGE         3

#define DB_BACKUP_CLOSE_FILE        4

#define DB_BACKUP_END               5

#define DB_BACKUP_READ_RENAME_LOG   6

/**************************/

/* Backup file constants  */

/**************************/

#define DB_BACKUP_MAX_FILE          12

#define DB_BACKUP_WRITE_FILE        -1

#define DB_BACKUP_TRANS_LOG_FILE    -2

/****************************/

/* db_environment constants */

/****************************/

#define DB_ENV_FLAGS                0       /* Short int */

#define DB_ENV_ENGVERSION           1       /* String */

#define DB_ENV_ENGNAME              2       /* String */

#define DB_ENV_DBNAME               3       /* String */

#define DB_ENV_SRVNAME              4       /* String */

#define DB_ENV_SRVVERSION           5       /* String */

#endif


ODBC Programming
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 34. ODBC Programming

About this chapter

The Open Database Connectivity (ODBC) interface is a C programming language interface defined by Microsoft Corporation as a standard interface to database management systems in the Windows and Windows NT environments.

ODBC reference online—The primary documentation for ODBC application development provided with SQL Anywhere is the ODBC application programming interface (API) online Help.

Applications using the ODBC interface can work with many different database systems. SQL Anywhere supports the ODBC API on DOS, OS/2, and QNX in addition to the Windows and Windows NT environments. By having multi-platform ODBC support, SQL Anywhere makes portable database application development much easier.

This chapter presents information for those developing ODBC interfaces to SQL Anywhere. Users of application development systems that already have ODBC support do not need to read this chapter.

 ODBC C language programming

 ODBC programming for the Macintosh


ODBC C language programming
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 34. ODBC Programming

ODBC C language programming

The ODBC interface is defined by a set of function calls, called the ODBC API (Application Programming Interface).

To write ODBC applications for SQL Anywhere, you need:

♦	The SQL Anywhere software.

♦	A C compiler capable of creating programs for your environment.

♦	The Microsoft ODBC Software Development Kit (Optional) (available on the Developer Network CD) which provides additional tools for testing ODBC applications as well as sample drivers.

 Fundamentals

 Compiling and linking an ODBC application

 A first example

 Error checking

 Cursors in ODBC

 Procedures and triggers in ODBC

 ODBC conformance

 The sample program


Fundamentals
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 34. ODBC Programming

ODBC C language programming

Fundamentals

Although the interface to ODBC is through function calls, database access is specified using SQL statements passed as strings to ODBC functions.

The following fundamental objects are used for every ODBC program. Each object is referenced by a handle.

♦	Environment Every ODBC application must allocate exactly one environment using SQLAllocEnv, and must free it at the end of the application using SQLFreeEnv. An environment handle is of type HENV.

♦	Connections An application can have several connections associated with its environment. Each connection must be allocated using SQLAllocConnect and freed using SQLFreeConnect. Your application can connect to a data source using either SQLConnect, SQLDriverConnect or SQLBrowseConnect, and disconnect using SQLDisconnect. A connection handle is of type HDBC.

♦	Statements Each connection can have several statements, each allocated using SQLAllocStmt and freed using SQLFreeStmt. Statements are used both for cursor operations (fetching data) and for single statement execution (e.g. INSERT, UPDATE and DELETE). A statement handle is of type HSTMT.

All access to these objects is through function calls; the application cannot directly access any information about the object from its handle. In the Windows and Windows NT environments, all the function calls are described in full detail in the ODBC API help file (ODBCAPI.HLP) provided with the Windows and Windows NT installations of SQL Anywhere.


Compiling and linking an ODBC application
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 34. ODBC Programming

ODBC C language programming

Compiling and linking an ODBC application

Every C source file using ODBC functions must include one of the following lines:

♦	Windows 3.x   #include "winodbc.h"

♦	DOS   #include "dosodbc.h"

♦	32-bit DOS   #include "ds32odbc.h"

♦	OS/2   #include "os2odbc.h"

♦	Windows 95 and NT   #include "ntodbc.h"

♦	QNX    #include "qnxodbc.h"

♦	32-bit QNX   #include "qnxodbc.h"

These files all include the main ODBC include file ODBC.H, which defines all of the functions, data types and constant definitions required to write an ODBC program. The file ODBC.H and the environment specific include files are installed in the H subdirectory of the SQL Anywhere installation directory (usually C:\SQLANY50).

Once your program has been compiled, you must link with the appropriate library file to have access to the ODBC functions:

♦	Windows 3.x   ODBC.LIB, which defines the entry points into the Driver Manager ODBC.DLL. If you connect to a SQL Anywhere database in Windows, ODBC.DLL will load the SQL Anywhere ODBC driver, WOD50W.DLL.

♦	DOS   WODBCWCL.LIB, which is a large model WATCOM C library. You will also need the SQL Anywhere interface library DBLIBWCL.LIB.

♦	   WODBCMCL.LIB, which is a large model Microsoft C library. You will also need the SQL Anywhere interface library DBLIBMCL.LIB.

♦	   WODBCBCL.LIB, which is a large model Borland C library. You will also need the SQL Anywhere interface library DBLIBBCL.LIB.

♦	32-bit DOS   WODBCWFG.LIB, which is a 32-bit flat model WATCOM C library. You will also need the SQL Anywhere interface library DBLIBWFG.LIB.

♦	OS/2   WODBC2.LIB, which defines the entry points into the SQL Anywhere ODBC driver, WOD502.DLL.

♦	Windows 95 and NT   WODBC32.LIB, which defines the entry points into the Driver Manager ODBC32.DLL. If you connect to a SQL Anywhere database in Windows NT, ODBC32.DLL will load the SQL Anywhere ODBC driver, WOD50T.DLL.

♦	32-bit QNX   odbc3r.lib, which is a 32-bit WATCOM C library. You will also need the SQL Anywhere interface library dblib3r.lib.


A first example
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 34. ODBC Programming

ODBC C language programming

A first example

The following is a simple ODBC program:

{

   HENV   env;

   HDBC   dbc;

   HSTMT   stmt;

   SQLAllocEnv( &env );

   SQLAllocConnect( env, &dbc );

   SQLConnect( dbc, "sademo", SQL_NTS,

               "dba", SQL_NTS, "sql", SQL_NTS );

   SQLSetConnectOption( dbc, SQL_AUTOCOMMIT, FALSE );

   SQLAllocStmt( dbc, &stmt );

   /* Delete all the order items for order 2015 */

   SQLExecDirect( stmt,

      "delete from sales_order_items where id=2015",

       SQL_NTS );

   /* Use rollback to undo the delete */

   SQLTransact( env, dbc, SQL_ROLLBACK );

   SQLFreeStmt( stmt, SQL_DROP );

   SQLDisconnect( dbc );

   SQLFreeConnect( dbc );

   SQLFreeEnv( env );

}

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').

SQLExecDirect   Executes the SQL statement specified in the parameter.

SQLTransact   Used to perform COMMIT and ROLLBACK statements marking the end of a transaction. You should not use SQLExecDirect to perform COMMIT or ROLLBACK.


Error checking
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 34. ODBC Programming

ODBC C language programming

Error checking

The previous example did not check for any errors. Errors in ODBC are reported using the return value from each of the ODBC API function calls and the SQLError function.

Every ODBC API function returns a RETCODE which is one of the following status codes:

♦	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 when a value being returned is too long for the buffer provided by the application.

♦	SQL_ERROR   The function did not complete due to an error. You can 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, and 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 help file 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 returns the information for one error and removes the information for that error. If you do not call SQLError to remove all errors, the errors are removed on the next function call which passes the same handle as a parameter.

The following program fragment uses SQLError and return codes:

HDBC dbc;

HSTMT stmt;

RETCODE retcode;

UCHAR errmsg[100];

. . .

retcode = SQLAllocStmt( 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( "Failed SQLAllocStmt", 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;

}

. . .

Note that each call to SQLError passes in 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 will get any error associated with the environment handle.

The return value from SQLError may seem confusing. It returns 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.

The examples pass the null pointer for some of the parameters to SQLError. The help file contains a full description of SQLError and all its parameters.


Cursors in ODBC
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 34. ODBC Programming

ODBC C language programming

Cursors in ODBC

ODBC cursors are similar to cursors in Embedded SQL (see "Cursors in Embedded SQL"). A cursor is opened using SQLExecute or SQLExecDirect, rows are fetched using SQLFetch or SQLExtendedFetch and the cursor is closed using SQLDropStmt.

To get values from a cursor, the application can use either SQLBindCol before a fetch or SQLGetData after a fetch.

The following code fragment opens and reads a cursor. Error checking has been omitted to make the example easier to read.

. . .

HDBC dbc;

HSTMT stmt;

RETCODE retcode;

long emp_id;

char emp_lname[20];

SQLAllocStmt( dbc, &stmt );

SQLExecDirect( stmt,

            "select emp_id,emp_lname

            from employee", SQL_NTS );

SQLBindCol( stmt, 1, SQL_C_LONG, &emp_id,

            sizeof(emp_id), NULL );

SQLBindCol( stmt, 2, SQL_C_CHAR, &emp_lname,

            sizeof(emp_lame), NULL );

for(;;) {

   retcode = SQLFetch( stmt );

   if( retcode == SQL_NO_DATA_FOUND ) break;

   print_employee( emp_id, emp_lname);

}

/* Using SQL_CLOSE closes the cursor

   but does not free the statement */

SQLFreeStmt( stmt, SQL_CLOSE );

. . .


Procedures and triggers in ODBC
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 34. ODBC Programming

ODBC C language programming

Procedures and triggers in ODBC

Procedures can be both created and called using ODBC. Triggers can also be created. Refer to "Using Procedures, Triggers, and Batches" for a full description of stored procedures and triggers.

There are two types of procedures in SQL Anywhere; those that return result sets and those that do not. Use SQLNumResultCols to tell the difference. The number of result columns will be 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 SQLSetParam to assign a storage area for each parameter marker whether it is an INPUT, OUTPUT or INOUT parameter.

The following example creates and calls a procedure. 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;

SQLSetParam( stmt, 1, SQL_C_LONG, SQL_INTEGER, 0,

            0, &i, NULL );

SQLExecDirect( stmt, "CALL Increment( ? )",

            SQL_NTS );

SQLNumResultCols( stmt, &num_col );

do_something( i );

The following example calls a procedure that returns a result set. In the example, the variable "num_col" will have the value two, 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_lame[ 20 ];

/* Create the procedure */

SQLExecDirect( stmt,

      "CREATE PROCEDURE employees()" \

      " RESULT( emp_id CHAR(10), emp_lname CHAR(20))"\

      " BEGIN" \

      " SELECT emp_id, emp_lame FROM employee" \

      " END", SQL_NTS );

/* Call the procedure - print the results */

SQLExecDirect( stmt, "CALL employees()", SQL_NTS );

SQLNumResultCols( stmt, &num_col );

SQLBindCol( stmt, 1, SQL_C_CHAR, &emp_id,

            sizeof(emp_id), NULL );

SQLBindCol( stmt, 2, SQL_C_CHAR, &emp_lname,

            sizeof(emp_lname), NULL );

for( ;; ) {

   retcode = SQLFetch( stmt );

   if( retcode == SQL_NO_DATA_FOUND ) {

   retcode = SQLMoreResults( stmt );

   if( retcode == SQL_NO_DATA_FOUND ) break;

} else {

   do_something( emp_id, emp_lname );

}

}


ODBC conformance
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 34. ODBC Programming

ODBC C language programming

ODBC conformance

The SQL Anywhere ODBC driver supports all of the ODBC Version 2.5 API functions (Core, Level 1 and Level 2) under Windows 95 and Windows NT. ODBC Version 2.1 support is provided for Windows 3.x. However, the driver cannot handle the following ODBC features:

♦	Asynchronous statement execution   Specifying the SQL_ASYNC_ENABLE value for fOption to SQLSetStmtOption and SQLSetConnectOption is an error, and SQLCancel is supported only as an equivalent to SQLFreeStmt( SQL_CLOSE ).

♦	Unsupported functions   SQL strings passed as a parameter to SQLPrepare, SQLExecDirect or SQLNativeSql which use one of the following database functions return an error because the functions are not supported by SQL Anywhere.

♦	REPLACE

♦	TIMESTAMPADD

♦	TIMESTAMPDIFF

♦	DATABASE


The sample program
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 34. ODBC Programming

ODBC C language programming

The sample program

A sample ODBC program, ODBC.C, is supplied in the CXMP subdirectory of the SQL Anywhere installation directory (usually C:\SQLANY50). The program performs the same actions as the embedded SQL dynamic cursor example program. See "Database examples" for a description of the associated embedded SQL program.

Building the sample program

Along with the sample program is a batch file, MAKEALL.BAT, that can be used to compile the sample program for the various environments and compilers supported by SQL Anywhere. For OS/2 the command is MAKEALL.CMD. For QNX, use the shell script makeall.. The format of the command is as follows:

makeall odbc {Platform} {Compiler} [DOS Extender]

The first parameter is "odbc", meaning compile the ODBC example. The same batch file also compiles the embedded SQL programs.

The second parameter is the platform in which the program will be run. The platform can be one of:

♦	DOS   compile for 16-bit DOS.

♦	DOS32   compile for 32-bit DOS. Use 4G to specify Rational DOS/4GW as the DOS Extender parameter.

♦	WINDOWS   compile for 16-bit Windows.

♦	WIN32    compile for 32-bit Windows using the Watcom C 32-bit Windows support.

♦	WINNT   compile for Windows NT or Windows 95.

♦	OS232   compile for OS/2.

♦	QNX   compile for 16-bit or 32-bit QNX.

♦	The third parameter is the compiler to use to compile the program. The compiler can be one of:

♦	WC   use Watcom C or Watcom C/32

♦	MC    use Microsoft C

♦	BC   use Borland C

♦	CS   use IBM C Set++

Building the sample program as an NT service

The example program ODBC., when compiled for Windows NT, runs optionally as a service.

The two files containing the example code for NT services are the source file NTSVC.C and the header file NTSVC.H.  The code allows the linked executable to be run as either a regular executable or as an NT service.

To run the compiled example as an NT service:

♦	Start the SQL Anywhere Service Manager.

♦	Click New.  The Service Type window is displayed.

♦	Click Sample Application, and click OK. The Edit SQL Anywhere Service Configuration window is displayed.

♦	Enter a service name.

♦	Click Path, and select the sample program (ODBCNT.EXE) from the CXMP subdirectory of the installation directory.

♦	Click OK to install the service.

♦	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.

This example has been tested with the Watcom C/C++ 10.5 compiler and the Microsoft Visual C++ 2.0 compiler.


ODBC programming for the Macintosh
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 34. ODBC Programming

ODBC programming for the Macintosh

When the Macintosh version of SQL Anywhere becomes available, developers of client applications other than PowerBuilder applications should follow the guideline in this section. Failure to do so could have severe effects on performance.

You should define a callback function to be used by the SQL Anywhere ODBC driver when it encounters an event it does not know how to handle. This callback function is particularly important if an update event gets into the application's queue. If this update event is not explicitly handled, and hence remains in the queue, the interprocess communication between the SQL Anywhere ODBC driver and the engine or client slows down dramatically, because of the high priority assigned to update events by the Macintosh operating system.

To define the callback function, you should include the provided C language header file EVENTCB.H. This header file has the following contents:

#define WSQL_OPT_REGISTER_CALLBACK_EVENTS   1900

typedef void pascal   (MAC_EVENT_CALLBACK)( EventRecord * theEvent );

typedef MAC_EVENT_CALLBACK *   MAC_EVENT_CALLBACK_PTR;

You should define the callback function as follows (the name may be changed).

#include "eventcb.h"

static void pascal EventHandler( EventRecord * theEvent )

{

   switch( theEvent->what ) {

      // The usual event processing goes here.

      // MUST process updateEvt fully, even if

      // just discarding as shown here.

      case updateEvt:

         BeginUpdate( (WindowPtr) theEvent->message );

         EndUpdate( (WindowPtr) theEvent->message );

         break;

   }

}

Other events may also be handled; updateEvt must be handled to avoid performance degradation.

The following fragment illustrates how to use the callback function.

extern void main()

{

   // ...

   SQLAllocConnect( env, &connection );

      // normal connection stuff

      SQLSetConnectOption( connection,

   WSQL_OPT_REGISTER_CALLBACK_EVENTS,

      (UDWORD) EventHandler );

   // ...

}


The WSQL DDE Server
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 35. The WSQL DDE Server

About this chapter

WSQL DDE Server is a Windows application which enables you to access and alter data in SQL Anywhere databases using Dynamic Data Exchange (DDE). This means that applications which can use DDE can access data directly, without having to use other database-querying applications such as ISQL. Many applications such as Excel and programming environments such as Visual Basic support the DDE protocol.

WSQL DDE Server can put query results on the clipboard, or return a memory buffer containing the query results. It can also send commands to the database engine, such as COMMIT or UPDATE.

Some applications have a limit on the number of characters which they can send at one time using DDE. For this reason, WSQL DDE Server can build a command or query piece by piece before executing it.

 DDE concepts

 Using WSQL DDE Server

 Excel and WSQL DDE Server

 Word and WSQL DDE Server

 Visual Basic and WSQL DDE Server


DDE concepts
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 35. The WSQL DDE Server

DDE concepts

The following sections provide an introduction to dynamic data exchange (DDE).

 What is DDE?

 DDE conversations

 Sending and receiving data and commands using DDE

 DDE links


What is DDE?
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 35. The WSQL DDE Server

DDE concepts

What is DDE?

DDE is a method of interprocess communication, that is, a method for passing data back and forth between applications. DDE uses a client/server system: client applications such as Excel request data from server applications, such as WSQL DDE Server.


DDE conversations
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 35. The WSQL DDE Server

DDE concepts

DDE conversations

An organized exchange of data using DDE is called a conversation. DDE conversations are distinguished by a three-level identification scheme: each conversation employs a service name, a topic name, and an item name.

At the top level is the service name. The WSQL DDE Server application uses the service name WSQLDDE. All conversations between a client application and WSQL DDE Server must use this service name.

The second level is the topic name. The topic name identifies the user and (optionally) specifies which SQL Anywhere database he wishes to query. The topic name must be of the form UserName,Password,Database or UserName,Password. (In the latter case, the default database environment is chosen.)

The third level is the item name. The item name further specifies the action to be performed by WSQL DDE Server. For instance, Connect and Clear are valid item names when sending data to WSQL DDE Server, while Column_Names_And_Data is a valid item name when requesting information from WSQL DDE Server.

Attempts to start a DDE conversation without a service name or a topic name are called wildconnects, and are not supported by WSQL DDE Server.


Sending and receiving data and commands using DDE
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 35. The WSQL DDE Server

DDE concepts

Sending and receiving data and commands using DDE

There are three main ways for a client to exchange information with a server: poking, executing, and requesting. These three operations are called DDE transactions (not to be confused with database transactions).

♦	Poke   send information from the client to the server. Typically, the client will poke data specifying a query to the server, and set the item name to a command acting upon the data.

♦	Execute   send the command directly to the database engine. No data is returned by a DDE execute transaction, and item names are ignored.

♦	Request   lets WSQL DDE Server know that the client wants to receive a memory buffer containing the results of a query. (The query must have already been added to the query buffer.) WSQL DDE Server does not support warm or hot request links (see below).


DDE links
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 35. The WSQL DDE Server

DDE concepts

DDE links

Methods of data exchange are often called links. There are three types of DDE links:

♦	A cold link occurs when the client requests data and the server immediately supplies the data.

♦	A warm link occurs when the server advises the client that some data that the client is interested in has changed. It is then the client's responsibility to request the data. WSQL DDE Server does not support warm links.

♦	A hot link occurs when the server sends a piece of data to the client as soon as the data changes. WSQL DDE Server does not support hot links.


Using WSQL DDE Server
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 35. The WSQL DDE Server

Using WSQL DDE Server

The WSQL DDE Server executable has the file name WSQLDDE.EXE, and will usually be run from your c:\sqlany50 directory.

 The WSQL DDE Server window

 Initiating a DDE conversation with WSQL DDE Server

 Communicating with the WSQL DDE Server


The WSQL DDE Server window
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 35. The WSQL DDE Server

Using WSQL DDE Server

The WSQL DDE Server window

The WSQL DDE Server window consists of an output window and a menu bar. The output window is updated every time WSQL DDE Server processes a command. It also displays any errors which have occurred. (If an error occurs, a message box will also inform you.) Every line of the output window begins with the DDE conversation number of the application which sent the command or caused the error. The output window will display the last five hundred commands and errors.

The menu bar has one item, File, which has the following selections:

♦	About WSQL DDE Server   Display general information about WSQL DDE Server.

♦	Clear Output Window   Erase the contents of the output window.

♦	Exit   Leave WSQL DDE Server. If there are still active DDE conversations, then a message box will ask you to confirm your decision to exit.


Initiating a DDE conversation with WSQL DDE Server
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 35. The WSQL DDE Server

Using WSQL DDE Server

Initiating a DDE conversation with WSQL DDE Server

A DDE conversation must be initiated before exchanging data using WSQL DDE Server. Two pieces of information are used to initiate a conversation with WSQL DDE Server: the service name and the topic name.

♦	The service name must be WSQLDDE.

♦	The topic name identifies the user, and optionally, the database to be used. It is a string of the form User,Password,Database or just User,Password. (Optionally, periods may be used instead of commas.)

Database connection is separate—The database is not activated or connected to when the DDE conversation is initialized. This occurs when the Connect command is sent.


Communicating with the WSQL DDE Server
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 35. The WSQL DDE Server

Using WSQL DDE Server

Communicating with the WSQL DDE Server

Once a conversation is initiated, there are three ways of communicating with WSQL DDE Server: poking, executing and requesting. The three methods are documented on the following pages.

Poking commands to WSQL DDE Server

Poking sends two pieces of data from the client application to WSQL DDE Server: a data buffer and an item name specifying what to do with the data.

POKE item-name data-buffer

There are five WSQL DDE Server functions which you can access through poking: Connect, Disconnect, Add, Clear and Clip.

Connecting to a database

POKE CONNECT

Before any queries or commands can be sent to the database engine, you must connect to the database. To do this, set the item name to Connect. WSQL DDE Server will attempt to connect to the database environment mentioned in the DDE topic. If the database engine is not running, then WSQL DDE Server will attempt to start it.

If there is no database name mentioned in the topic, then WSQL DDE Server will try to connect to an already-running database engine. (If there is no running engine, then the connect will fail.)

The contents of the data buffer are ignored.

One connection only—It is not possible to have more than one connection per conversation.

Disconnecting from a database

POKE DISCONNECT

To terminate the current connection, set the item name to Disconnect. The contents of the data buffer are ignored.

Terminate the conversation separately—This command terminates the connection to the database, but does not terminate the DDE conversation (though it will usually be the last command sent in a DDE conversation).

Adding to the query buffer

POKE ADD text

Some applications (such as Excel) can only poke 255 characters at a time. Many SQL queries, however, are longer than this. For this reason, WSQL DDE Server allows an application to build a complete query string by adding together many shorter strings. To add text to the query buffer, set the item name to Add and the data buffer to the text you wish to add to the buffer.

Each DDE conversation has its own query buffer.

Clearing the query buffer

POKE CLEAR text

To reset the query buffer, set the item name to Clear and the data buffer to the string you wish to place at the beginning of the query buffer.

Putting query results on the clipboard

POKE

     CLIP_DATA

   | CLIP_COLUMN_NAMES

   | CLIP_COLUMN_NAMES_AND_DATA

...  [ text ]

There are three very similar commands which put the results of a query on the clipboard. Each adds the contents of the data buffer to the query buffer, and then evaluates the query stored in the query buffer. The results of the query are formatted and placed on the clipboard. Most applications have a Paste command which will retrieve the query results from the clipboard.

The three commands are:

Clip_Data   place the results of the query on the clipboard in text format. Each datum will be separated by a tab character. Each row will be terminated by a newline character.

Clip_Column_Names   place the names of the columns referenced in the query onto the clipboard. Column names will be separated by tab characters, and the row will be terminated by a newline character.

Clip_Column_Names_And_Data   does both operations, appending the data after the column names.

Executing database commands

EXECUTE [ text ]

Executing a command adds the command to the query buffer and sends the contents of the query buffer directly to the database engine. It is very similar to doing an EXECUTE IMMEDIATE from Embedded SQL. Executed commands do not return results to the application, so queries cannot be executed. Item names are ignored when doing a DDE execute transaction.

Requesting

REQUEST

     DATA

   | COLUMN_NAMES

   | COLUMN_NAMES_AND_DATA

Requesting data gives the calling application a block of memory containing the requested data, as opposed to placing the data on the clipboard for the application to access. (This is useful for applications that do not support clipboard access.)

WSQL DDE Server only supports cold request links. (That is, it is the application's responsibility to request data. See the section on DDE above for more information about link types.) WSQL DDE Server places the results of the query currently in the query buffer into a memory block and then sends the address of the memory to the application.

There are three valid item names for the request transaction: Data, Column_Names and Column_Names_And_Data. The structure of the data in the buffer is identical to that of the data placed on the clipboard when doing a Clip_Data, Clip_Column_Names or Clip_Column_Names_And_Data command. (See above.)


Excel and WSQL DDE Server
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 35. The WSQL DDE Server

Excel and WSQL DDE Server

There are a number of Excel Macro Sheet DDE functions that can access the WSQL DDE Server DDE Server. The Query.to.clipboard macro shown in demonstrates the use of Macro Sheets to initiate and terminate a DDE conversation, connect and disconnect from a database, and clip data. (Excel supports Execute, although this example doesn't use it.)

This macro is included in the WSQLDDE.XLW workbook in the directory C:\SQLANY50\ACCXMP\EXCEL. You should start the database engine and the WSQL DDE Server before loading the workbook. You will see the sheet in Follow the instructions to clip data from the database and paste it on the sheet.


Word and WSQL DDE Server
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 35. The WSQL DDE Server

Word and WSQL DDE Server

Microsoft Word Basic supports DDE. The following example contains sample Word Basic code to access the WSQL DDE Server DDE server. The two different ways of retrieving the data are demonstrated: using the clipboard and receiving the data directly.

Sub MAIN

   ' Initialize a DDE channel to the database

   chan = DDEInitiate("WSQLDDE", "dba,sql,sademo")

   ' Connect to the database

   DDEPoke chan, "connect", ""

   ' Get the data using the clipboard

   DDEPoke chan, "clip_data", \

      "select emp_lname \

      from employee where emp_id = 102"

   EditPaste

   ' Insert the data directly into the document

   DDEPoke chan, "clear", \

      "select emp_lname \

      from employee where emp_id = 105"

   Insert DDERequest$(chan, "data")

   ' Disconnect from the database

   DDEPoke chan, "disconnect", ""

   ' Terminate the DDE connection

   DDETerminate(chan)

End Sub


Visual Basic and WSQL DDE Server
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 35. The WSQL DDE Server

Visual Basic and WSQL DDE Server

The following Visual Basic code fragment initializes a DDE conversation, connects to a database, requests and clips some data, executes a command and finally disconnects from the database.

LinkTimeout property—Visual Basic controls have a LinkTimeout property, which specifies the amount of time the application will wait for a DDE function to execute. Some database queries can be time-consuming, so you may wish to set the LinkTimeout property to -1 (wait forever). The problem with this is that if there are link errors it may seem as though your computer has `locked up'. If this happens, try pressing the ALT or ESC key to abort the operation.

' INITIALIZING A DDE CONVERSATION

MyTextBox.LinkTopic = "WSQLDDE|DBA,SQL,sademo"

   ' Set the service name to WSQLDDE

   ' and the topic name to DBA,SQL,sademo

MyTextBox.LinkMode = 2

   ' Two is cold link mode

' The DDE conversation has now been initiated,

' but the Database Engine has not been accessed.

' CONNECTING

MyTextBox.LinkItem = "Connect"

MyTextBox.LinkPoke

   ' The Connect command has just been poked.

   ' WSQL DDE Server tries to connect to

   ' the sample database using

   ' the user name dba and password sql.

   ' The contents of MyTextBox are ignored

   ' and unaltered.

'REQUESTING A QUERY

MyTextBox.LinkItem = "Clear"

MyTextBox.Text = "SELECT * FROM department"

MyTextBox.LinkPoke

   ' The query buffer is cleared and

   ' the SELECT statement is

   ' added to it.

MyTextBox.LinkItem = "Column_Names_And_Data"

MyTextBox.LinkRequest

   ' The LinkRequest sets MyTextBox to

   ' the results of the query

   ' that we just added to it.

   ' Had the LinkItem been "Column_Names"

   ' then only the column names

   ' would have appeared in MyTextBox.

   ' Similarly, if the LinkItem

   ' had been "Data" then just the data rows

   ' would have appeared.

'CLIPPING A QUERY

MyTextBox.LinkItem = "Clear"

MyTextBox.Text = " SELECT emp_lname, emp_id FROM employee "

MyTextBox.LinkPoke

   ' The query buffer is cleared and

   ' the SELECT statement is added.

MyTextBox.LinkItem = "Add"

MyTextBox.Text = " WHERE emp_id < 150 "

MyTextBox.LinkPoke

   ' The query buffer now contains:

   ' SELECT emp_lname, emp_id

   ' FROM employee WHERE emp_id < 150

MyTextBox.LinkItem = "Clip_Data"

MyTextBox.Text = " ORDER BY emp_lname "

MyTextBox.LinkPoke

   ' The ORDER BY clause is appended to the

   ' query buffer, and the

   ' data from the query is placed on the

   ' clipboard. The LinkItem

   ' could also have been "Clip_Column_Names" or

   ' "Clip_Column_Names_And_Data"

MyTextBox.Text = ClipBoard.GetText( )

   ' This pastes the contents of the clipboard

   ' to the text box.

'EXECUTING A COMMAND

MyTextBox.LinkItem = "Clear"

MyTextBox.Text = "UPDATE employee SET dept_id=200 "

MyTextBox.LinkPoke

MyTextBox.LinkExecute " WHERE emp_lname='Chin' "

' The WHERE clause is appended to the query buffer and the command

' UPDATE employee SET dept_id=200 WHERE emp_lname='Chin'

' is sent to the database engine.

'DISCONNECTING

MyTextBox.LinkItem = "Disconnect"

MyTextBox.LinkPoke

   ' The connection to the database

   ' engine is terminated.

   ' The DDE conversation still exists,

   ' so another Connect

   ' could be done.

 The test application

 Running the test application


The test application
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 35. The WSQL DDE Server

Visual Basic and WSQL DDE Server

The test application

There is a Visual Basic test application (both source and executable) included with WSQL DDE Server (see directory C:\SQLANY50\ACCXMP\VB) which demonstrates the features of WSQL DDE Server. The filename is WSQLDDET.EXE. You can take a look at the source by loading the project WSQLDDET.MAK if you have the Visual Basic software.


Running the test application
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 35. The WSQL DDE Server

Visual Basic and WSQL DDE Server

Running the test application

Start the database engine (on the sample database), WSQL DDE Server, and the test application. A window containing a large text box, a small text box and a button marked Connect will appear. Press the Connect button. (If you want to use a different username or password than the default, enter them into the small text box before connecting. The contents of this box will become the Link Topic.)

Pressing the Connect button terminates the current DDE conversation (if one exists), starts a new DDE conversation with the given topic, and pokes a Connect to the DDE server. After a moment, the Test Application screen will change. There will now be a combobox and seven buttons: Disconnect, Query to Clipboard, Query to Memory, Add to Buffer, Clear Buffer, Clear Screen and Execute Command.

The combo box is used to select which portions of a result set you want. There are three selections, which allow you to see just column names, just data, or both column names and data.

The Disconnect button terminates the database connection, but not the DDE conversation. (The DDE conversation can be terminated by quitting the test application.) You will then be given the option to connect again. You should disconnect from the database engine before quitting the test application.

Pressing the Query to Clipboard button first adds the contents of the small text box to the query buffer, and then gets the query results from the database engine. The result set is placed on the clipboard, and the clipboard contents are placed in the large text box. Finally, the query buffer is cleared.

Pressing the Query to Memory button first adds the contents of the small text box to the query buffer, and then sends a DDE request transaction. The result set is placed directly in the large text box. The query buffer is then cleared.

Pressing the Execute button first adds the contents of the small text box to the query buffer, and then executes the contents of the query buffer. The execute command does not put any data in the large text box.

The execute command uses the DDE execute transaction.

Pressing the Add to Query Buffer button adds the contents of the small text box to the query buffer.

Pressing the Clear Query Buffer button erases the whole query buffer.

Pressing the Clear Screen button clears the contents of the large text box.


The WSQL HLI Interface
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

About this chapter

WSQL HLI is a high level callable interface which allows you to access data in SQL Anywhere databases from a variety of applications and programming environments. This chapter documents the WSQL HLI programming interface.

WSQL HLI is available as a DLL for Windows, OS/2 and Windows NT.

The WSQL HLI call interface allows you to access information in SQL Anywhere databases from a programming environment such as Visual Basic in Windows or REXX in OS/2. It allows programmers to use a record-at-a-time cursored database interface similar to Embedded SQL or a set-at-a-time interface similar to the WSQL DDE Server . WSQL HLI can process queries and database commands using host variables, return query results from both individual fields and entire query result sets, and provide error information. Most of the functionality is provided by the wsqlexec function which takes a string as a parameter. This string is parsed by WSQL HLI, and the appropriate Embedded SQL commands are executed.

 DLL concepts

 Using WSQL HLI

 Host variables with WSQL HLI

 WSQL HLI functions

 wsqlexec command strings

 CLIP HLI Statement

 CLOSE HLI Statement

 COMMIT HLI Statement

 DECLARE HLI Statement

 DROP HLI Statement

 EXECUTE HLI Statement

 FETCH HLI Statement

 OPEN HLI Statement

 PREPARE HLI Statement

 ROLLBACK HLI Statement

 SET CONNECTION HLI Statement

 START USING DATABASE HLI Statement

 STOP USING DATABASE HLI Statement

 WSQL HLI and Visual Basic

 WSQL HLI and REXX


DLL concepts
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

DLL concepts

A Dynamic Link Library (DLL) is a collection of functions which are available to any program. DLL's are different from regular applications in that they are unable to execute on their own. They are always called from another application or DLL.

The main benefits of DLL's are:

♦	their ability to be shared by many independent applications at the same time (DLL's are a global resource).

♦	they provide a high level of abstraction. An application does not need to know how the DLL works to use it.

♦	their high upgradeability. If a new version of a DLL is released you should be able to use the new one immediately, without modifying, recompiling or relinking your software.

♦	their ease of use. In some programming environments all you have to do is declare which DLL you are using. Calling DLL functions is then identical to calling normal language functions. (DLL's are sometimes called plug-and-play for this reason.)

The WSQL HLI DLL is a shared system resource—it can be used by multiple applications. However, internally, all resources such as database connections, statements and cursors are managed on a per task basis. Thus, there will not be any name conflicts between various applications using the DLL.


Using WSQL HLI
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

Using WSQL HLI

The WSQL HLI DLL has the file name WSQLCALL.DLL (Windows 3.x), WSQLCAL2.DLL (OS/2), or WSQLCALT.DLL (Windows NT and Windows 95).


Host variables with WSQL HLI
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

Host variables with WSQL HLI

A host variable is a variable in an application which can be used (referenced) by WSQL HLI. Host variable support is an optional feature and requires the application to provide callback functions for host variable access. The Visual Basic interface does not provide host variable support. OS/2 REXX host variable support is provided by WSQL HLI (see "WSQL HLI and REXX").

Host variables provide a convenient way to use program variables in SQL commands that are sent to WSQL HLI. You can also use host variables to FETCH values directly into program variables rather than using the wsqlgetfield function.

For example, if you had an application variable myquery containing a SELECT statement that you wanted to execute, then you could prepare it like this:

return_code = wsqlexec("PREPARE Stmt1 FROM :myquery");

The following rules should be noted:

♦	Host variable names must be under 30 characters long.

♦	To distinguish host variables from regular text, they must be prefixed with a colon. (See the example above.)

WSQL HLI needs some way to reference host variables, to both access and change their contents. To do this, a pair of callback functions must be supplied to WSQL HLI. When WSQL HLI encounters a host variable, it calls the appropriate callback function to either retrieve or set the variable's value. For this reason, it is necessary to call the function wsqlregisterfuncs before using any host variables. wsqlregisterfuncs takes two parameters, both pointers to callback functions. The first function, PutHostVar specifies a host variable name and the string to put in it. The second function, GetHostVar specifies a host variable name and the address of a string pointer to fill in with its value. See "wsqlregisterfuncs" for more information.

For example, the statement:

wsqlexec( "FETCH Cursor1 INTO :host1" );

would call the function registered as PutHostVar with the name host1 and the value of the item fetched (converted to a string). Your application's callback function would then identify the host variable and save the new value.


WSQL HLI functions
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

WSQL HLI functions

WSQL HLI has six functions:

Ordinal	Function Name	Comments
3	wsqlexec	execute a command
4	wsqlgetfield	get a result column value
5	wsqlgetcolumnname	get a result column name
6	wsqlquerytomem	retrieve results in one piece of memory
7	wsqllasterror	get error string for last error
8	wsqlregisterfuncs	register host variable callback functions
The Windows DLL entry points are all FAR PASCAL functions and all pointers are far pointers. The OS/2 DLL entry points are all _System functions. The Windows NT entry points are all __stdcall functions.

All functions return a long integer containing a SQL error code indicating the success or failure of the function. The wsqllasterror function can be called to get a meaningful message about the last error. See "SQL Anywhere Database Error Messages" for a complete list of error codes. The following sections describe these functions in detail.

 wsqlexec

 wsqlgetfield

 wsqlgetcolumnname

 wsqlquerytomemdelim

 wsqlquerytomem

 wsqllasterror

 wsqlregisterfuncs


wsqlexec
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

WSQL HLI functions

wsqlexec

The wsqlexec function is used to process all SQL requests, such as PREPAREing statements or OPENing cursors. In OS/2, the wsqlexecrexx function can be used from a REXX program (see "WSQL HLI and REXX").

The C prototype for this function is:

extern long _entry wsqlexec(

   char *command

);

The command must be one of the following:

♦	CLIP

♦	CLOSE

♦	COMMIT

♦	DECLARE

♦	DROP

♦	EXECUTE

♦	FETCH

♦	OPEN

♦	PREPARE

♦	ROLLBACK

♦	SET CONNECTION

♦	START USING DATABASE

♦

♦	STOP USING DATABASE

These commands are described fully in "wsqlexec command strings".


wsqlgetfield
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

WSQL HLI functions

wsqlgetfield

The wsqlgetfield function is used to retrieve the data value from one column of the most recently FETCHed row of a query result set.

The C prototype for this function is:

extern long _entry wsqlgetfield(

   char   * cname,

   int      offset,

   short   * ind,

   char   * result,

   int      len

);

cname   name of a cursor which is opened and positioned at the row of the query result set that you want to examine.

offset   the column number which you wish to examine. Columns are numbered from left to right starting at 0.

ind   indicator variable. If the result buffer is too small, then the required length is put in the indicator variable. If the requested item is null, then the indicator is set to -1, and if there is a conversion error, then the indicator is set to -2. Otherwise, it is set to zero.

result   string buffer which will be filled in with the requested column name. The result buffer should be allocated and freed by the calling application.

len   maximum number of characters that can be placed in the result buffer.


wsqlgetcolumnname
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

WSQL HLI functions

wsqlgetcolumnname

The wsqlgetcolumnname function is used to get one column name of a query result set.

The C prototype for this function is:

extern long _entry wsqlgetcolumnname(

   char   * cname,

   int      offset,

   short   * ind,

   char   * result,

   int      len

);

cname   name of a cursor that has been opened.

offset   the column number whose name you want. Columns are numbered from left to right starting at 0.

ind   indicator variable. If the result buffer is too small, then the required length is put in the indicator variable. Otherwise, it is set to zero.

result   string buffer that will be filled in with the requested column name. The result buffer should be allocated and freed by the calling application.

len   maximum number of characters that can be placed in the result buffer.


wsqlquerytomemdelim
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

WSQL HLI functions

wsqlquerytomemdelim

The wsqlquerytomemdelim function is used to place a portion of a query result set into a memory buffer.

If column names are requested, then the resulting buffer will start with a list of column names.

If data is requested, then the buffer will contain all of the rows of the query result set from the current cursor position to the end of the result set. If the supplied buffer is not large enough, then as many rows as will fit will be placed in the result buffer, and the cursor will be positioned on the row following the last one placed in the buffer. If this occurs, then the return code will be SQLE_HLI_MORE_DATA_AVAILABLE.

Each row will end with the specified rowdelim and the data in the row will be separated by coldelim.

The C prototype for this function is:

extern long _entry wsqlquerytomemdelim(

   char * cursor,

   char * result,

   int len,

   bool data,

   bool names,

   char * coldelim,

   char * rowdelim

);

cursor   name of a cursor that is opened and (if you want data) positioned at the first row of data to be returned.

result   character buffer, allocated by the calling application. It will be filled in with as many rows as possible from the result set, starting at the current cursor position.

len   maximum number of characters that should be placed in the result buffer.

data   flag indicating that you want the buffer to contain query results. If data is zero, then no query results will be returned. Otherwise, query results will be returned, starting from the current cursor position.

names   flag indicating that you want a list of column names. If it is zero, then column names will not be included. Otherwise, a list of column names will be placed at the beginning of the returned buffer.

coldelim   A string that will be placed between each column name and each column value.

coldelim   A string that will be placed at the end of the column names and at the end of each data row.


wsqlquerytomem
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

WSQL HLI functions

wsqlquerytomem

The wsqlquerytomem is similar to the wsqlquerytomemdelim function except the column delimiter is fixed as the tab character and the row delimiter is a carriage return - linefeed pair.

The C definition for this function is:

extern long _entry wsqlquerytomem(

   char * cursor,

   char * result,

   int len,

   bool data,

   bool names,

)

{

   return( wsqlquerytomemdelim( cursor, result,

   len, data, names, ".t", ".r.n" ) );

}

The parameters are the same as those for wsqlquerytomemdelim.


wsqllasterror
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

WSQL HLI functions

wsqllasterror

The wsqllasterror function is used to provide a meaningful message explaining the last error condition. :note.The return code will be the number of the last error condition.

The C prototype for this function is:

extern long _entry wsqllasterror(

   char * buffer,

   int len

);

buffer   string buffer which will be filled in with an error message. It should be allocated and freed by the calling application.

len   maximum number of characters that can be placed in buffer. For a complete description of SQL Anywhere errors, see "SQL Anywhere Database Error Messages".


wsqlregisterfuncs
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

WSQL HLI functions

wsqlregisterfuncs

The wsqlregisterfuncs function is used to register callback functions for host variables (see "Host variables with WSQL HLI"). Host variable use is optional. It is best used when your application system has the concept of variables and you can provide a callback function to access them. It is not necessary to register callback functions in order to use host variables from REXX.

The C prototype for this function is:

extern long _entry wsqlregisterfuncs(

   p_callback PutHostVar,

   p_callback GetHostVar

);

The Windows callbacks are FAR PASCAL functions that are exported and all pointers are far pointers. The OS/2 callbacks are _System functions. The Windows NT callbacks are __stdcall functions.

PutHostVar   pointer to a callback function with the following prototype:

extern long _callback PutHostVar(

   char * name,

   short ind,

   char * value,

   int len

);

name   name of the host variable whose value WSQL HLI wishes to change.

ind   indicator variable for the value of the host variable. See "Indicator variables" for details.

value   new value for the host variable. It is always a null terminated string.

len   number of characters in value.

return value   a SQL error code indicating the success or failure of the operation. If the host variable or its value are invalid, then the return value should be the SQLE_HLI_BAD_HOST_VAR_VALUE or SQLE_HLI_BAD_HOST_VAR_NAME codes.

GetHostVar   pointer to a callback function with the following prototype:

extern long _callback GetHostVar(

   char * name,

   short * ind,

   char * * value,

   int * len

);

name    name of the host variable whose value is needed by WSQL HLI.

ind    place to put an indicator value, if one exists, for the host variable.

value    pointer to a string buffer pointer. The GetHostVar function should fill in value with a pointer to a buffer containing the value of the host variable.

len    number of characters placed in value by the function.

return value    a SQL error code indicating the success or failure of the operation. If the host variable is invalid, then the return value should be the SQLE_HLI_BAD_HOST_VAR_NAME code.


wsqlexec command strings
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

wsqlexec command strings

This section contains a detailed description of each command that can be passed as a string to the wsqlexec function. The syntax conventions used in this chapter are the same as those used in "Watcom-SQL Language Reference".

The commands are listed one per page with a syntax summary box at the top of the page.


CLIP HLI Statement
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

CLIP HLI Statement

Syntax

CLIP

    NAMES

   | DATA

   | BOTH

... cursor-name

cursor-name:   identifier, or host variable

Purpose

To place query results on the Windows or Windows NT clipboard.

Description

This command places a query result set on the system clipboard. The cursor-name must identify an open cursor.

If NAMES is specified, then the clipboard contents will be a single row containing the column names of the result set of the indicated cursor. The names will be separated by tab characters and terminated with a carriage return / linefeed.

If DATA is specified, then the clipboard contents will be the entire query result set starting from the current cursor position. Each row will be terminated with a carriage return / linefeed and the values within a row will be separated by tab characters.

If BOTH is specified then the row of names will be placed on the clipboard first, followed by the rest of the result set.

If the BOTH or DATA keyword is specified then the cursor will be positioned just after the last row of the query result set.


CLOSE HLI Statement
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

CLOSE HLI Statement

Syntax

CLOSE cursor-name

cursor-name:   identifier, or host variable

Purpose

Close the named cursor.

Description

This command closes the indicated cursor. The cursor must have been previously OPENed.

This command is functionally similar to the Embedded SQL command CLOSE. See "CLOSE statement".


COMMIT HLI Statement
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

COMMIT HLI Statement

Syntax

COMMIT

Purpose

To make changes permanent to the database.

Description

COMMIT makes any changes you have made to the database permanent.

This command is functionally similar to the SQL command COMMIT. See "COMMIT statement" for details.


DECLARE HLI Statement
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

DECLARE HLI Statement

Syntax

DECLARE cursor-name CURSOR FOR statement-name

cursor-name:   identifier, or host variable

statement-name:   identifier, or host variable

Purpose

To declare a cursor. Cursors are used to retrieve query results a record at a time.

Description

This command associates a cursor with a particular statement. The statement name must have been used in a previous PREPARE command. Once declared, a cursor can be opened and fetched.

All cursors are scrollable in both directions and will remain open across COMMIT and ROLLBACK commands.

This command is functionally similar to the Embedded SQL command DECLARE. See "DECLARE CURSOR statement".


DROP HLI Statement
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

DROP HLI Statement

Syntax

DROP statement-name

statement-name:   identifier, or host variable

Purpose

To free resources used by a statement.

Description

The DROP command frees resources used by a prepared statement, and unreserves the statement name (and any associated cursors). If there is a cursor associated with this statement, then it will be CLOSEd and unreserved.

This command is functionally similar to the Embedded SQL command DROP STATEMENT.


EXECUTE HLI Statement
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

EXECUTE HLI Statement

Syntax

1. EXECUTE statement-name [ USING hostvariablelist ]

statement-name:   identifier, or host variable

2. EXECUTE IMMEDIATE statement

statement:   string or host variable

Purpose

To execute a SQL statement that is not a query (SELECT).

Description

This command executes a SQL statement. Format 1 executes a named statement which has been prepared. The prepared statement may contain host variable parameters. If it does, and no :keyword.USING clause is specified, then the values of the host variables named in the statement will be requested. If a USING clause is specified, then the parameters will be set to the values of the host variables in the list. The number of host variables in the list must match the number of host variable parameters specified in the statement.

Format 2 will take a SQL statement and PREPARE, EXECUTE and DROP it. The statement in Format 2 is specified as a string with single quotes, or as a host variable.

Any SQL statement except a SELECT statement may be executed.

This command is functionally similar to the Embedded SQL command EXECUTE. See "EXECUTE statement".


FETCH HLI Statement
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

FETCH HLI Statement

Syntax

FETCH [ ABSOLUTE offset | RELATIVE offset ]

... cursor [ INTO hostvariablelist ]

offset:   number

cursor-name:   identifier, or host variable

hostvariablelist:   list of host variables

Purpose

To retrieve a row from a cursor.

Description

This command repositions a cursor and optionally puts the data from the new row into host variables (see "Host variables with WSQL HLI"). If a host variable list is not used, then the data from the new row can be obtained using the wsqlgetfield function.

The named cursor must be open.

The ABSOLUTE clause places the cursor on row number offset. The RELATIVE clause places the cursor offset rows forward or backward (if negative) in the result set. If both clauses are omitted, then the default behavior is to move the cursor forward one row.

This command is functionally similar to the Embedded SQL command FETCH. See "FETCH statement".


OPEN HLI Statement
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

OPEN HLI Statement

Syntax

OPEN cursor-name

cursor-name:   identifier, or host variable

Purpose

To open a cursor.

Description

This command opens a previously declared cursor to access information from a database. The cursor must have been DECLAREd, and the associated statement must have been prepared.

All cursors are opened WITH HOLD, that is, they are left open and at the same row if a COMMIT or ROLLBACK is performed.

When opened, the cursor is positioned just before the first row of the result set.

This command is functionally similar to the Embedded SQL command OPEN. See "OPEN statement".


PREPARE HLI Statement
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

PREPARE HLI Statement

Syntax

PREPARE statement-name FROM statement

statement-name:   identifier, or host variable

statement:   string or host variable

Purpose

To prepare and name a SQL statement.

Description

This command prepares a statement to be executed or used for a cursor. Any statement previously prepared with the same name is overwritten.

To free resources associated with a prepared statement, use the DROP command.

This command is functionally similar to the Embedded SQL command PREPARE. See "PREPARE statement".


ROLLBACK HLI Statement
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

ROLLBACK HLI Statement

Syntax

ROLLBACK

Purpose

To undo changes made to the database since the last COMMIT or ROLLBACK.

Description

This command undoes any changes made to the database since the last COMMIT or ROLLBACK.

This command is functionally similar to the SQL command ROLLBACK. See "ROLLBACK statement" for details.


SET CONNECTION HLI Statement
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

SET CONNECTION HLI Statement

Syntax

SET CONNECTION [ connection-name ]

connection-name:   identifier, or host variable

Purpose

To change active connections.

Description

This command changes the current database connection. You can use the START USING DATABASE command several times naming the connection each time. Each time, the new connection becomes the current connection. You can use the SET CONNECTION statement to make the named connection current.

This command is functionally identical to the Embedded SQL command of the same name. See "SET CONNECTION statement".


START USING DATABASE HLI Statement
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

START USING DATABASE HLI Statement

Syntax

1. START USING DATABASE [ engine-name:database-name ]

   ...    [ AS connection-name ] [ USER ] userid

   ...    IDENTIFIED BY password

2. START USING DATABASE connect-string

engine-name:   identifier, or host variable

database-name:   identifier, or host variable

connection-name:   identifier, or host variable

userid:   identifier, or host variable

password:   identifier, or host variable

Purpose

Form 1: to establish a connection to a database engine or server. Form 2: to start a new database on an existing engine or server.

Description

Form 1 of the START USING DATABASE statement establishes a connection to a database engine or server. If database is omitted then WSQL HLI connects to the default database environment. If there is no such database environment then this command fails.

You can optionally name the connection. This is useful if you wish to simultaneously use more than one connection to the same or different database engines or servers.

This command is functionally similar to the Embedded SQL command CONNECT. See "CONNECT statement".

Form 2 of the START USING DATABASE statement with a connection string does not try to connect to this starting database; it merely starts it. The connection string specifies the database. For a description of connection strings, see "Database connection parameters".

To connect to the database, once it is started, use the START USING DATABASE statement a second time, with form 1.


STOP USING DATABASE HLI Statement
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

STOP USING DATABASE HLI Statement

Syntax

1. STOP USING DATABASE [ connection-name ]

2. STOP USING DATABASE connect-string

connection-name:   identifier, or host variable

Purpose

Form 1: to terminate a connection to a database engine or server. Form 2: to stop a database.

Description

Form 1 of this statement terminates a connection to the database.

This statement is functionally similar to the Embedded SQL command DISCONNECT. See "DISCONNECT statement". Form 2 of this statement stops, or unloads, a database from a named server.


WSQL HLI and Visual Basic
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

WSQL HLI and Visual Basic

Visual Basic 3.0 introduced ODBC support. By using ODBC, you can develop a Visual Basic application that uses SQL Anywhere that can easily use another ODBC data source sometime in the future. WSQL HLI is still a good alternative when using ODBC does not make sense for your application.

It is very easy to use DLL's from the Visual Basic environment. All that is necessary is for the functions to be declared in the global code area or a general-declarations area. Since Visual Basic does not support callback functions, the wsqlregisterfuncs function cannot be used. Host variables are not used in Visual Basic.

To declare WSQL HLI functions, put the following statements in your project's global code area

Declare Function wsqlexec Lib "wsqlcall.dll" (ByVal cmd$) As Long

Declare Function wsqlgetfield Lib "wsqlcall.dll" (ByVal cur$, ByVal i As Integer, ind As Integer, ByVal buf$, ByVal l As Integer) As Long

Declare Function wsqlgetcolumnname Lib "wsqlcall.dll" (ByVal cur$, ByVal i As Integer, ind As Integer, ByVal buf$, ByVal l As Integer) As Long

Declare Function wsqllasterror Lib "wsqlcall.dll" (ByVal buf$, ByVal i As Integer) As Long

Declare Function wsqlquerytomem Lib "wsqlcall.dll" (ByVal buf$, ByVal cur$, ByVal dta As Integer, ByVal names As Integer) As Long

These declarations can also be found in the Test Application's global area. The filename is WSQLDLLT.GLB.

It is important that all string buffers that are to be filled in by WSQL HLI be fixed-length strings. WSQL HLI will not work properly with variable-length strings. Also, all returned character string buffers will be terminated with a null (zero) character.

 Visual Basic example

 The sample application

 Running the sample application


Visual Basic example
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

WSQL HLI and Visual Basic

Visual Basic example

The following code fragments are part of a Visual Basic application that uses WSQL HLI.

In the global module or form, declare the DLL or QuickLibrary functions which are going to be used. Now the five functions can be used in other subroutines, such as the following code fragment:

ret = wsqlexec("START USING DATABASE sademo AS Con1 USER dba IDENTIFIED BY sql")

ret = wsqlexec("SET CONNECTION Con1")

   ' We are now connected to the

   ' sample database engine

ret = wsqlexec("PREPARE stmt1 FROM 'SELECT * FROM department' ")

   ' The single quotes are optional.

ret = wsqlexec("DECLARE cur1 CURSOR FOR stmt1")

   ' The cursor name 'cur1' and the statement name    'stmt1' are now

   ' reserved.

ret = wsqlexec("OPEN cur1")

   ' The cursor is now open and positioned before the    ' first row of the query.

ret = wsqlexec( "CLIP BOTH cur1" )

MyTextBox.Text = ClipBoard.GetText( )

   ' MyTextBox now contains the query results.

   ' cur1 is positioned just after the last

   ' row of the query.

' ---------------------------------------------

Dim ret As Long

Dim ind%

Dim buf As String * 100

ret = wsqlexec("FETCH ABSOLUTE 1 cur1")

   ' cur1 is now positioned on the

   ' first row of the query.

   '

   ' buf is a 100 byte string, ind% is an integer:

ret = wsqlgetfield("cur1", 1, ind%, buf, 100)

   ' translation - put the first 100 characters of the

   ' second column of the current row of cursor "cur1"    into

   ' the string buf, and if there are more than 100

   ' characters, put how many characters

   ' there are in    ind%.

   ' buf now contains "R & D", ind contains zero.

ret = wsqlgetcolumnname("cur1", 0, ind%, buf, 100)

   ' translation - put the first

   '  100 characters of the name

   ' of the first column of the result

   ' set of cursor "cur1"

   ' into the string buf$, and if there

   are more than 100  characters, put how many

   ' characters there are in ind%.

   ' buf$ now contains "dept_id", ind% contains zero.

ret = wsqlexec("CLOSE cur1")

ret = wsqlexec("DROP STATEMENT stmt1")

   ' the cursor and statement are no longer valid.

   '

   ' two ways of executing a statement:

   ' method one:

ret = wsqlexec("EXECUTE IMMEDIATE INSERT INTO department VALUES ('220','Eastern Sales', 502)")

   ' method two:

ret = wsqlexec("PREPARE stmt2 FROM INSERT INTO department VALUES ('230','Western Sales', 502)")

ret = wsqlexec("EXECUTE stmt2")

ret = wsqlexec("DROP stmt2")

' handling errors:

ret = wsqlexec("EXECUTE IMMEDIATE DROP TABLE BogusTable ")

   ' There is no such table - ret is set to -141.

   ' Get more information:

ret = wsqllasterror(buf, 100)

   ' buf now contains "table 'BogusTable' not found",

   ' a more meaningful error message

ret = wsqlexec("STOP USING DATABASE Con1")

   ' database connection is terminated.


The sample application
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

WSQL HLI and Visual Basic

The sample application

There is a Visual Basic sample application (both source and executable) included with WSQL HLI that demonstrates some features of WSQL HLI. The filename is WSQLDLLT.EXE, and you can take a look at the source by loading the project WSQLDLLT.MAK from Visual Basic. (Visual Basic is not included with the SQL Anywhere software.)

This example is found in the ACCXMP\VB subdirectory of the SQL Anywhere installation directory (usually C:\SQLANY50).


Running the sample application
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

WSQL HLI and Visual Basic

Running the sample application

The sample application is a simple display utility which shows the contents of the employee table, one record at a time. Start the sample database and the test application. Once the database engine and the test application have started, press the Connect button. After a moment, a slider bar will appear, the Connect button will have become the Disconnect button, and the text boxes will be displaying the first record in the employee table.

Use the slider bar to examine any of the one hundred entries in the employee table. When you are done, press the Disconnect button and close the application.


WSQL HLI and REXX
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

WSQL HLI and REXX

There is a special entry point in the WSQL HLI for OS/2 specifically for REXX that can be called directly from REXX and allows REXX variables to be used in SQL commands as host variables (see "Host variables with WSQL HLI"). This function must be registered by any REXX program that uses WSQL HLI. Put the following statement in your REXX program:

call RXFUNCADD 'SQLEXEC', 'WSQLCAL2', 'WSQLEXECREXX'

WSQL HLI is very similar to the IBM DB/2 REXX programming interface. START USING DATABASE and STOP USING DATABASE are supported by the wsqlexecrexx entry point. You may wish to register the function a second time to make your REXX program more portable:

all RXFUNCADD 'SQLDBS', 'WSQLCAL2', 'WSQLEXECREXX'

WSQL HLI only contains a subset of the IBM DB/2 REXX programming interface.

 Error codes and messages

 REXX examples


Error codes and messages
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

WSQL HLI and REXX

Error codes and messages

The REXX interface function returns an error code. The error code is also assigned to the REXX stem variable SQLCA.SQLCODE. See "SQL Anywhere Database Error Messages" for a complete list of error codes. An error message is assigned to the REXX variable SQLMSG.


REXX examples
User's Guide

PART 5. The SQL Anywhere Programming Interfaces

CHAPTER 36. The WSQL HLI Interface

WSQL HLI and REXX

REXX examples

The following short REXX program fetches 10 employees from the sample database using WSQL HLI.

* WSQL HLI from REXX */

call RXFUNCADD 'SQLDBS', 'WSQLCAL2', 'WSQLEXECREXX'

call RXFUNCADD 'SQLEXEC', 'WSQLCAL2', 'WSQLEXECREXX'

call sqldbs 'START DATABASE MANAGER'

call sqldbs 'START USING DATABASE SADEMO USER DBA IDENTIFIED BY SQL'

stmt = "select emp_lname from employee"

call sqlexec "PREPARE s1 FROM :stmt"

call CheckSQLError

call sqlexec "DECLARE c1 CURSOR FOR s1"

call CheckSQLError

call sqlexec "OPEN c1"

call CheckSQLError

do 10

/* fetch a row */

call sqlexec "FETCH c1 INTO :lname:Indlname"

call CheckSQLError

say lname Indlname

end

call sqlexec "CLOSE c1"

call CheckSQLError

call sqldbs "STOP USING DATABASE ALL"

exit

CheckSQLError:

if SQLCA.SQLCODE = 0 then do

   say SQLCA.SQLCODE SQLMSG

end

return

There is a more substantial example in the ACCXMP\REXX subdirectory of the SQL Anywhere installation directory (usually C:\SQLANY50).


SQL Anywhere Reference
User's Guide

PART 6. SQL Anywhere Reference

This part provides reference information for the Sybase SQL Anywhere database management system, including the software components, SQL language, error messages, system tables, and so on.

 CHAPTER 37. SQL Anywhere Components

 CHAPTER 38. Watcom-SQL Language Reference

 CHAPTER 39. SQL Anywhere Data Types

 CHAPTER 40. Watcom-SQL Functions

 CHAPTER 41. Watcom-SQL Statements

 CHAPTER 42. SQL Anywhere Database Error Messages

 CHAPTER 43. SQL Preprocessor Error Messages

 CHAPTER 44. Differences from Other SQL Dialects

 CHAPTER 45. SQL Anywhere Limitations

 CHAPTER 46. SQL Anywhere Keywords

 CHAPTER 47. SQL Anywhere System Procedures and Functions

 CHAPTER 48. SQL Anywhere System Tables

 CHAPTER 49. SQL Anywhere System Views


SQL Anywhere Components
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

About this chapter

SQL Anywhere includes a set of utility programs in addition to the database engine. The utility programs include tools for backing up databases and performing other database administration tasks. This chapter provides reference information for each of the SQL Anywhere components, including the database engine and the accompanying utility programs.

  Users of SQL Anywhere for Unix platforms, please see "SQL Anywhere components overview"

 SQL Anywhere components overview

 Registry entries and environment variables

 Software component return codes

 The database engine

 The Backup utility

 The Collation utility

 The Compression utility

 The Erase utility

 The Information utility

 The Initialization utility

 The ISQL utility

 The Log Translation utility

 The Open Server Gateway

 The Open Server Information utility

 The Open Server Stop utility

 The REBUILD batch or command file

 The SQL Remote Database Extraction utility

 The SQL Remote Message Agent

 The Stop utility

 The Transaction Log utility

 The Uncompression utility

 The Unload utility

 The Upgrade utility

 The Validation utility

 The Write File utility

 The SQL Preprocessor


SQL Anywhere components overview
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

SQL Anywhere components overview

This chapter presents reference information on the programs and database administration utilities that are part of SQL Anywhere. The utilities can be accessed from Sybase Central, from ISQL, or as command-line programs.

For comprehensive documentation on Sybase Central, see the Sybase Central online Help. For an introduction to the Sybase Central database administration tool, see the chapter "Managing Databases with Sybase Central". For information on the SQL Anywhere Service Manager, see the chapter "Running Programs as Services".

The SQL Anywhere programs use a set of system environment variables. These variables are described in "Registry entries and environment variables".

The SQL Anywhere programs also use a standard set of return codes. These return codes are described in "Software component return codes".

SQL Anywhere for Unix platforms—The syntax for starting SQL Anywhere components on Unix platforms differs slightly from other platforms. On Unix platforms such as Sun Solaris, IBM AIX, HPUX or QNX, SQL Anywhere programs are executed with commands typed in the lower case, and program files do not have an .EXE suffix.
Versions of SQL Anywhere for Unix platforms have only the command line utilities, a character mode ISQL utility and a standalone version of the database available.


Registry entries and environment variables
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

Registry entries and environment variables

SQL Anywhere uses a set of system variables to store various types of  information necessary for running the software. These system variables are stored in registries, INI files, or environment variables, depending on the operating system. Not all system variables need to be set in all circumstances.

The following is a list of system variables used by SQL Anywhere and a description of what they are used for.

 SQLANY environment variable

 SQLCONNECT environment variable

 SQLPATH environment variable

 SQLREMOTE environment variable

 SQLSTART environment variable

 TMP environment variable


SQLANY environment variable
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

Registry entries and environment variables

SQLANY environment variable

Syntax

SQLANY = path

Description

The SQLANY environment variable is used to contain the directory where SQL Anywhere is installed. The default installation directory is C:\SQLANY50. The install procedure automatically adds the SQLANY environment variable to your startup environment. The SQLANY variable is used by the batch files or command files that build the Embedded SQL examples.

In QNX, SQL Anywhere is installed in a fixed directory and the SQLANY variable is not required.


SQLCONNECT environment variable
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

Registry entries and environment variables

SQLCONNECT environment variable

Syntax

SQLCONNECT = keyword=value ; ...

SQLCONNECT = keyword#value ; ...

Description

The SQLCONNECT environment variable specifies connection parameters that are used by several of the database tools to connect to a database engine or network server. This string is a list of parameter settings of the form KEYWORD=value, delimited by semicolons. The number sign "#" is an alternative to the equals sign, and should be used when setting the connection parameters string in the SQLCONNECT environment variable, as using "=" inside an environment variable setting is a syntax error.

The keywords are from the following table.

Verbose keyword	Short form
Userid	UID
Password	PWD
ConnectionName	CON
EngineName	ENG
DatabaseName	DBN
DatabaseFile	DBF
DatabaseSwitches	DBS
AutoStop	AutoStop
Start	Start
Unconditional	UNC
DataSourceName	DSN
For a description of the connection parameters, see "Database connection parameters".


SQLPATH environment variable
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

Registry entries and environment variables

SQLPATH environment variable

Syntax

SQLPATH = path;...

PATH = path;...

Description

ISQL searches along SQLPATH for ISQL command files and Help files before searching the system path.


SQLREMOTE environment variable
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

Registry entries and environment variables

SQLREMOTE environment variable

Syntax

SQLREMOTE = path

Description

Addresses for the FILE message link in SQL Remote replication are subdirectories of the SQLREMOTE environment variable. This variable should point to a shared directory.


SQLSTART environment variable
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

Registry entries and environment variables

SQLSTART environment variable

Syntax

SQLSTART = start-line

SQLSTARTW = start-line

Description

Historical. The SQLSTART environment variable information has been added to the SQLCONNECT environment variable as the start parameter.


TMP environment variable
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

Registry entries and environment variables

TMP environment variable

Syntax

TMP = directory

TMPDIR = directory

TEMP = directory

Description

The database engine creates temporary files for various operations such as sorting and performing unions. These temporary files will be placed in the directory specified by the TMP, TMPDIR, or TEMP environment variables. (The database engine takes the first one of the three that it finds.)

If none of the environment variables is defined, temporary files are placed in the current directory.


Software component return codes
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

Software component return codes

All database components use the following executable return codes. The header file SQLDEF.H has constants defined for these codes.

Code	Explanation
0	Success
1	General failure
2	Invalid file format, and so on
3	File not found, unable to open, and so on
4	Out of memory
5	Terminated by user
6	Failed communications
7	Missing required database name
8	Client/server protocol mismatch
9	Unable to connect to database engine
10	Database engine not running
11	Database server not found
254	Reached stop time
255	Invalid parameters on command line


The database engine
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The database engine

Syntax

dbeng50 [engine-switches][database-file [database-switches], ...]

rtdsk50 [engine-switches][database-file [database-switches], ...]

Windows 3.xsyntax

dbeng50w [engine-switches][database-file [database-switches], ...]

rtdsk50w [engine-switches][database-file [database-switches], ...]

dbeng50s [engine-switches][database-file [database-switches], ...]

rtdsk50s [engine-switches][database-file [database-switches], ...]

Switch	Description
@filename	Read in switches from configuration file
@envvar	Read in switches from environment variable
-b	Run in bulk operations mode
-c cache-size	Set maximum cache size
-d	Disable asynchronous I/O (OS/2, Windows NT, NetWare only)
-df	Force direct I/O (Windows 3.1, DOS only)
-di	Use direct I/O if possible (Windows 3.1, DOS only)
-ga	Automatically shut down after last database closed
-gb level	Set database process priority class to level
-gc num	Set checkpoint timeout period
-gd level	Set database starting permission
-ge size	Sets the stack size for threads that run external functions
-gf	Disable firing of triggers
-gk level	Set permission for stopping the engine using DBSTOP
-gn num	Set number of threads
-gp size	Set maximum page size
-gr num	Set maximum recovery time
-gs size	Set thread stack size
-gw num	Set the interval (in milliseconds) for background processing
-gx	Disable dual threading
-m	Truncate transaction log after checkpoint
-n name	Name the database engine
-q	Quiet mode—suppress output
-ta sec	Scan time for terminated applications:—default 30 seconds
-u	Use buffered disk I/O (Windows 95 and Windows NT only)
-v	Log old values of all columns on UPDATE or DELETE for all databases
-y	Run as a Windows 95 service
Recovery switches

Switch	Description
-a log-file	Apply named transaction log file
-f	Force database to start without transaction log
Database switches

Switch	Description
-m	Truncate transaction log after checkpoint
-n name	Name the database
-v	Log old values of all columns on UPDATE or DELETE
Description

There are several versions of the SQL Anywhere database engine, and each version has a different executable name. The database engine for platforms other than Windows 3.x is named DBENG50.EXE, the 32-bit and 16-bit Windows 3.x executables being DBENG50W.EXE and DBENG50S.EXE respectively. The runtime database engine is named RTDSK50.EXE, with the 32-bit and 16-bit Windows 3.x executables being named RTDSK50W.EXE and RTDSK50S.EXE respectively.

The SQL Anywhere standalone database engine is completely compatible with the SQL Anywhere network server (DBSRV50.EXE). Client applications developed on one run against the other without alteration. For information about the network server and its command-line switches, see the SQL Anywhere Network Guide.

The 32-bit versions of the Windows 3.x database engine have much better performance than the 16-bit versions. They require Windows 3.x running in enhanced mode.

The database engine can be started with a number of database files or no database files. Command-line switches specified before any databases apply to the engine and all databases. Switches specified after a particular database file apply only to that database.

Client applications can load additional databases dynamically after the database engine has started. However, only databases of the same or smaller page size can be loaded dynamically.

If a database-file is specified without a file extension, SQL Anywhere first looks for database-file with extension WRT (a write file), followed by database-file with extension DB.

The database engines are programs that run as a separate task.

In DOS, the database engines are DOS terminate and stay resident programs (TSRs), meaning that they will load into the memory of your computer and then return control to DOS.

Runtime database engines are available with the SQL Anywhere Desktop Runtime System for DOS, Windows 3.x, OS/2 and Windows 95 or NT.

The runtime engine does not allow ALTER, CREATE, COMMENT or DROP commands. GRANT and REVOKE will allow you to add new users and change passwords but changing permissions on tables is not allowed. Also, the runtime database engine does not employ a transaction log (although it is a fully transaction-processing database engine) and does not support stored procedures and triggers.

Supplying command-line switches in a configuration file—A set of command line switches can be stored in a configuration file or in an environment variable. The database engine can be instructed to use these switches using the @ command-line switch.

Engine switches

@filename   Read in command-line switches from the supplied file.

The file may contain line breaks, and may contain any set of command line switches. For example, the following command file holds a set of command line switches for an engine that starts with a cache size of 4 Mb, a name of myserver, and loads the sample database:

-c 4096

-n myserver

c:\sqlany50\sademo.db

If this configuration file is saved as C:\CONFIG.TXT, it can be used in an command line as follows:

DBENG50 @c:\config.txt

@environment-variable   Read in command-line switches from the supplied environment variable. The environment variable may contain any set of command line switches. For example, the first of the following pair of statements sets an environment variable holding a set of command line switches for a database server that starts with a cache size of 4 Mb and loads the sample database. The second statement starts the database server:

set envvar=-c 4096 c:\sqlany50\sademo.db

DBENG50 @envvar

-b   Use bulk operation mode. This is useful when loading large quantities of data into a database.

In bulk operations mode, the database server allows only one connection by one application. It does not keep a rollback log or a transaction log, and the multiuser locking mechanism is turned off. You should use a new log file when starting the database engine or server after loading data with the -b switch.

Bulk operation mode does not disable the firing of triggers.

  For more information on loading and unloading data, see "Tuning bulk operations".

-c cache-size   Set the size of the cache. The database server uses extra memory for caching database pages if it is set aside in the cache. Any cache size less than 10000 is assumed to be K-bytes (1K = 1024 bytes). Any cache size 10000 or greater is assumed to be in bytes. The cache size may also be specified as nK or nM (1M = 1024K). By default, the database server usess 2 megabytes of memory for caching. The more cache that can be given the engine, the better will be its performance.

-d disable asynchronous I/O   This option applies to Windows NT, OS/2 and NetWare systems only. Use synchronous rather than asynchronous I/O. Asynchronous I/O is the default for these systems and should offer performance improvements.

-df force direct I/O   This option applies to DOS and Windows 3.x systems only. Use direct I/O rather than DOS I/O. DOS I/O is the default. See the -di option for a description of direct I/O.

-di use direct I/O if possible   This option applies for DOS and Windows 3.x only. Analyse the disk hardware and software and use direct I/O if possible. The default is to use DOS I/O.

As databases increase in size and get more fragmented, direct I/O can provide a significant increase in performance. However, direct I/O does not work with all disks. Using the -di option causes the engine or server to attempt to determine whether direct I/O will work with the current configuration. If direct I/O cannot be used, a message will be displayed on startup.

Windows 95 I/O—Asynchronous I/O is not supported in Windows 95 environments.

-ga   Applications can cause databases to be started and stopped  by the engine. Specifying this switch causes the engine to shutdown when the last database is stopped.

-gb level   OS/2 and Windows NT only. Sets the database process priority class to level. Level must be one of idle, normal (the default), high, or maximum. idle is provided for completeness, and maximum may interfere with the running of your computer. low and high are the commonly used settings.

-gc num   Sets the maximum desired length of time (in minutes) that the database server will run without doing a checkpoint.

When a database server is running with multiple databases, the checkpoint time specified by the first database started will be used unless overridden by this switch.

For more information about checkpoints, see the CHECKPOINT_TIME option in "SET OPTION statement".

-gd level   Set the database starting permission to level. This is the permission level required by a user to cause a new database file to be loaded by the server. The level can be one of the following:

♦	dba   Only users with DBA authority can start new databases.

♦	all   All users can start new databases (the default).

♦	none   Starting new databases is not allowed.

-ge size   Sets the stack size for threads running external functions, in bytes. The default is 16384 (16K). This switch is used only for OS/2, Windows NT, and NetWare.

-gf   Disables firing of triggers by the server.

-gk level   Sets the permission required to stop the database engine using DBSTOP to level. The level can be one of the following:

♦	dba   Only users with DBA authority can use DBSTOP to stop the engine.

♦	all   All users can use DBSTOP to stop the engine (the default).

♦	none   The engine cannot be stopped using DBSTOP.

-gn num   Sets the number of execution threads that will be used in the database server while running with multiple users.

For more information, see the THREAD_COUNT option in "SET OPTION statement".

When a database server is running with multiple databases, the thread count specified by the first database started will be used unless overridden by this switch.

-gp size   Sets the maximum page size allowed, in bytes. The size specified must be one of: 512, 1024, 2048, or 4096. When a database server is running with multiple databases, the page size specified by the first database will be used unless overridden by this switch. Without using this option, an attempt to load a database file with a page size larger than the page size of the database first loaded will fail.

-gr num   Sets the maximum desired length of time (in minutes) that the database server will take to recover from system failure.

For more information, see the RECOVERY_TIME option in "SET OPTION statement".

When a database server is running with multiple databases, the recovery time specified by the first database started will be used unless overridden by this switch.

-gs size   Sets the stack size of every thread in the server. The value entered is multiplied by four to produce the stack size in bytes.

-gw num   Sets the interval for background processing. At each interval, the engine carries out one I/O operation. The default setting is 500 (half a second).

-gx   Disables dual threading. This option is available for the Windows 95, Windows NT, OS/2, and NetWare versions.

-m   Truncate (delete) the transaction log when a checkpoint is done, either at shutdown or as a result of a checkpoint scheduled by the database engine. 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 (also definable 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 provided against media failure on the device containing 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.

Replicated databases—Do not use the -m option with databases that are being replicated as replication inherently relies on transaction log information.

-n name   Set the name of the database server. 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 C:\SQLANY50\SADEMO.DB and no -n switch is specified, then the name of the server will be sademo.

The server name can be used on the connect statement to specify to which server you wish to connect. In all environments, there is always a default database server that will be used if no server name is specified provided at least one database server or SQL Anywhere Client (DBCLIENT) is running on the computer.

-q   Operate quietly. Suppress all output.

-ta seconds   For Windows 3.x, Windows NT, and Windows 95 only. The database engine periodically scans the connection list and disconnects any connections associated with terminated applications. The scan period can be controlled using the -ta switch, and has a default value of 30 seconds. Setting the value to zero prevents scanning.

-u   Files are opened using the operating system disk cache in addition to the database cache. This option applies to the Windows 95 and Windows NT database servers only. While the operating system disk cache may improve performance in some cases, in general better performance is obtained without this switch, using the database cache only.

-v   Cause the database engine to record in the appropriate transaction log the previous values of each of the columns whenever a table row is updated or deleted. By default, the engine will only record enough information to uniquely identify the row (primary key values or values from a not null unique index). This switch is useful for working on a copy of a database file.

This option does not apply to the runtime database engine, which does not support transaction logs, or database files that are not using a transaction log.

-y   Runs database engine as a Windows 95 service. By registering the database engine as a Windows 95 service it continues to operate whether as users log on or off and shutdown commands are ignored.

  The database engine can also be run as an NT service. For more information, see the chapter "Running Programs as Services".

Recovery switches

-a log-file   Apply the named transaction log. This is used to recover from media failure on the database file. When this option is specified, the database server will apply the log and then terminate—it will not continue to run.

This option does not apply to the runtime database engine, which does not support transaction logs, or database files that are not using a transaction log.

For more information on recovery from media failure, see the chapter "Backup and Data Recovery".

-f   This option is used 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.

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 current directory, 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.

This option does not apply to the runtime database engine, which does not support transaction logs.

For more information on recovery, see the chapter "Backup and Data Recovery".

Database switches

-m   Truncate (delete) the transaction log when a checkpoint is done, either at shutdown or as a result of a checkpoint scheduled by the engine. 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 (also definable 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 provided against media failure on the device containing 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 switch is the same as the -m engine switch, but applies only to the database identified by the database-file command-line variable.

Replicated databases—Do not use the -m option with databases that are being replicated as replication inherently relies on transaction log information.

-n name   Set the name of the database. 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 file with the path and extension removed. For example, if the server is started on C:\SQLANY50\SADEMO.DB and no -n switch is specified, then the name of the database is sademo.

-v   Causes the database engine to record in the transaction log the previous values of each of the columns whenever a row of the specified database is updated or deleted. By default, the engine will only record enough information to uniquely identify the row (primary key values or values from a not null unique index). This switch is useful for working on a copy of a database file.

This option does not apply to the runtime database engine, which does not support transaction logs, or database files that are not using a transaction log.

The backup, initialization, unload, and validation utilities automatically load the database engine if it has not been previously loaded. The SQL Anywhere Client (DBCLIENT) can also be started automatically in this way. See "Registry entries and environment variables" and the respective commands for more details. If the database engine (or client) is started automatically, it will be unloaded automatically when the software is finished executing.


The Backup utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Backup utility

With the Backup utility, you can back up running databases, database files, transaction logs, and write files.

You can access the Backup utility in the following ways:

♦	From Sybase Central, for interactive use under Windows 95 or NT.

♦	From the ISQL Database Tools window.

♦	From the ISQL DBTOOL statement.

♦	From the system command line, using the DBBACKUP utility. This is useful for incorporating backup procedures into batch or command files.

The Backup utility makes a backup copy of all the files making up 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. Each file is 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. It is provided to allow a database to be backed up while other applications or users are using the database.

  For more information

For a description of suggested backup procedures, see the chapter "Backup and Data Recovery".

 Backing up a database from Sybase Central

 Backing up a database from the ISQL Database Tools window

 Backing up a database using the DBTOOL statement

 The DBBACKUP command-line utility

 Backup utility options


Backing up a database from Sybase Central
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Backup utility

Backing up a database from Sybase Central

 To back up a running database:

1	Connect to the database.

2	Right-click the database and click Backup in the popup menu. The Backup Wizard is displayed.

3	Follow the instructions in the Wizard.

 To back up a database file or a running database:

1	Open the Database Utilities folder in the left panel.

2	Double-click Backup Database in the right panel.

3	Follow the instructions in the wizard.

 For full information on backing up a database from Sybase Central, see the Sybase Central online Help. For more information about options, see "Backup utility options"


Backing up a database from the ISQL Database Tools window
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Backup utility

Backing up a database from the ISQL Database Tools window

 To use the Backup utility from the ISQL Database Tools window:

1	Select Database Tools from the Window menu.

2	Click Backup Database Files on the Tools list.

3	Enter a user ID and password to use when connecting to the database.

4	For a running database, enter a database name and server name (if more than one is running). For a database file, enter the filename (with path) and optionally a start line to specify command-line switches for the database engine or SQL Anywhere Client.

5	Click Backup, and select from the options displayed in the dialog.

6	Click OK to back up the database.


Backing up a database using the DBTOOL statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Backup utility

Backing up a database using the DBTOOL statement

Syntax

The syntax to access the Backup utility from the ISQL DBTOOL statement is as follows:

DBTOOL BACKUP TO directory

...     [DBFILE] [ WRITE FILE ][ [ TRANSACTION ] LOG ]

   | [ ALL FILES ]

...   | [ RENAME [ TRANSACTION ] LOG ]

   | [ TRUNCATE [ TRANSACTION ] LOG ]

...   [ NOCONFIRM ] USING connection-string


The DBBACKUP command-line utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Backup utility

The DBBACKUP command-line utility

Syntax

dbbackup [switches] directory

Windows 3.x syntax

dbbackw [switches] directory

Switch	Description
-c "keyword=value; ..."	Supply database connection parameters
-d	Only back up main database file
-k	Change backup transaction log naming convention
-l file	Live backup of transaction log to file
-o file	Log output messages to file
-q	Quiet mode—do not print messages
-r	Rename and start new transaction log
-t	Only back up transaction log
-w	Only back up write file
-x	Delete and restart transaction log
-y	Replace files without confirmation
If none of the switches -d, -t, or -w are used, all database files are backed up.

  For more information about the command-line switches, see "Backup utility options".


Backup utility options
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Backup utility

Backup utility options

Connection parameters   For a description of the connection parameters, see "Database connection parameters". If the connection parameters are not specified, connection paremeters from the SQLCONNECT environment variable are used, if set. The user ID must have DBA authority.

For the DBBACKUP command-line utility, this is the -c command-line switch. For example, the following statement backs up the sademo database running on the server sample_server, connecting as user ID DBA with password SQL:

dbbackup -c "eng=sample_server;dbn=sademo;uid=dba;pwd=sql"

Backup main database only   Back up the main database files only, without backing up the transaction log file or a write file, if one exists. For the DBBACKUP command-line utility, this is the -d command-line switch.

Change backup transaction log naming convention   This option changes the naming convention of the backup transaction log file to YYMMDDxx.LOG, where xx is a number from 00 to 99 and YYMMDD represents the current year, month and day. By default the name used for the backup transaction log file is identical to the file name of the transaction log being backed up. For the DBBACKUP command-line utility, this is the -k command-line switch.

Live backup   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 crashes. 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. For the DBBACKUP command-line utility, this is the -l (lower case L) command-line switch.

Output messages to log   Sends backup messages to a named log file. For the DBBACKUP command-line utility, this is the -o command-line switch.

Operate quietly   Do not display messages on a window. For the DBBACKUP command-line utility, this is the -q command-line switch. This option is not available from other environments.

Rename and start new transaction log   This option forces a checkpoint and the following three steps to occur:

♦	Step 1   A copy is made of the current working transaction log file and saved to the directory specified in the command line.

♦	Step 2   The current transaction log remains in its current directory, but is renamed using the format YYMMDDxx.LOG, where xx is a number from 00 to 99 and YYMMDD represents the current year, month and day. This file is then no longer the current transaction log.

♦	Step 3   A new transaction log file is generated that contains no transactions. It is given the name of the file previously considered the current transaction log and is used by the database engine as the current transaction log.

For the DBBACKUP command-line utility, this is the -r command-line switch.

Back up the transaction log file only   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). For the DBBACKUP command-line utility, this is the -t command-line switch.

Back up the database write file only   See DBWRITE for a description of database write files. For the DBBACKUP command-line utility, this is the -w command-line switch.

Delete and restart the transaction log   With this option, the existing transaction log is backed up, then the original is deleted and a new transaction log is started with the same name. This option causes the backup to wait for a point when all transactions from all connections are committed. For the DBBACKUP command-line utility, this is the -x command-line switch.

Operate without confirming actions   Without this option, you are prompted to confirm the creation of the backup directory or the replacement of a previous backup file in the directory. For the DBBACKUP command-line utility, this is the -y command-line switch.


The Collation utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Collation utility

With the Collation utility, you can extract a collation (sorting sequence) from the SYS.SYSCOLLATION system table of a database into a file suitable for creating a database using a custom collation.

The file produced by the Collation utility can be modified and used with Sybase Central or the -z option of DBINIT to create a new database with a custom collation.

Ensure that the label is changed on the line that looks like:

Collation label (name)

Otherwise, the collation cannot be used to create a database.

If you wish to create a custom collation but have not yet created a database, you should extract a collation from the sample database provided with SQL Anywhere.

For more information on custom collating sequences, see the chapter "Database Collations".

You can access the Collation utility in the following ways:

♦	From the ISQL Database Tools window.

♦	From the ISQL DBTOOL statement.

♦	From the system command line, using the DBCOLLAT command-line utility.

 Extracting a collation in the ISQL Database Tools window

 Extracting a collation using the DBTOOL statement

 The DBCOLLAT command-line utility

 Collation utility options


Extracting a collation in the ISQL Database Tools window
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Collation utility

Extracting a collation in the ISQL Database Tools window

 To use the Collation utility from the ISQL Database Tools window:

1	Select Database Tools from the Window menu.

2	Click Extract Collation from Database on the Tools list.

3	For a running database, enter a database name and server name (if more than one is running). For a database file, enter the filename (with path) and optionally a start line to specify command-line switches for the database engine or SQL Anywhere Client.

4	Click Extract, and select from the options displayed in the dialog.

5	Click OK to extract the collation file from the database.


Extracting a collation using the DBTOOL statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Collation utility

Extracting a collation using the DBTOOL statement

Syntax

The syntax to access the Collation utility from the ISQL DBTOOL statement is as follows:

DBTOOL UNLOAD COLLATION [ name ] TO filename

... USING connection-string

... [ EMPTY MAPPINGS ] [ HEX | HEXADECIMAL ] [ NOCONFIRM ]


The DBCOLLAT command-line utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Collation utility

The DBCOLLAT command-line utility

Syntax

dbcollat [switches] output-file

Windows 3.x syntax

dbcollw [switches] output-file

Switch	Description
-c "keyword=value; ..."	Supply database connection parameters
-e	Include empty mappings
-o filename	Output log messages to file
-q	Quiet mode — do not print messages
-x	Use hex for extended characters (7F-FF)
-y	Replace file without confirmation
-z col-seq	Specify collating sequence label
  For more information about the command-line switches, see "Collation utility options".


Collation utility options
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Collation utility

Collation utility options

Connection parameters   For a description of the connection parameters, see "Database connection parameters". If the connection parameters are not specified, connection paremeters from the SQLCONNECT environment variable are used, if set. The user ID must have DBA authority.

For the DBCOLLAT command-line utility, this is the -c command-line switch. For example, the following statement extracts a collation file from the sademo database running on the sample_server server, connecting as user ID DBA with password SQL:

dbcollat -c "eng=sample_server;dbn=sademo;uid=dba;pwd=sql" c:\sample\col

Include empty mappings   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. For the DBCOLLAT command-line utility, this is the -e command-line switch.

Output log messages to file   Redirect the log messages from the Collation utility to a named file. For the DBCOLLAT command-line utility, this is the -o command-line switch.

Operate quietly   Do not display messages on a window. For the DBCOLLAT command-line utility, this is the -q command-line switch. This option is not available from other environments.

Use hexadecimal for extended characters (7F to FF)    Extended single-byte characters (whose value is greater than hex 7F) may or may not appear correctly on your screen, depending on whether or not the code page in use on your computer is the same as the code page being used in the collation you are extracting. This option causes the Collation utility to write all characters at hex 7F or above as a two-digit hexadecimal number, in the form:

\xdd

(For example, \x80, \xFE). Normally, only characters from hex 00 to hex 1F, hex 7F and hex FF are written in hexadecimal form. For the DBCOLLAT command-line utility, this is the -x command-line switch.

Operate without confirming actions   Without this option, you are prompted to confirm replacing an existing collation file. For the DBCOLLAT command-line utility, this is the -y command-line switch.

Specify collating sequence label   Specify the label of the collation to be extracted. The names of the collation sequences can be found in the collation_label column of the SYS.SYSCOLLATION table. If this option is not specified, then the Collation utility extracts the collation being used by the database. For the DBCOLLAT command-line utility, this is the -z command-line switch.


The Compression utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Compression utility

With the Compression utility you can compress a database file. The Compression utility reads the given database file and create a compressed database file. Compressed database files are useful if disk space is limited. Compressed databases are usually 40 to 60 per cent of their original size. The database engine cannot update compressed database files: they must be used in conjunction with write files.

The Compression utility does not compress files other than the main database file.

You can access the Compression utility in the following ways:

♦	From Sybase Central, for interactive use under Windows 95 or NT.

♦	From the ISQL Database Tools window.

♦	From the ISQL DBTOOL statement.

♦	From the system command line, using the DBSHRINK command-line utility. This is useful for incorporating into batch or command files.

 Compressing a database in Sybase Central

 Compressing a database from the ISQL Database Tools window

 Compressing a database using the DBTOOL statement

 The DBSHRINK command-line utility

 Compression utility options


Compressing a database in Sybase Central
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Compression utility

Compressing a database in Sybase Central

 To compress a database file:

1	Open the Database Utilities folder in the left panel.

2	Double-click Compress Database in the right panel. The Compress Database Wizard is displayed.

3	Follow the instructions in the Wizard.

For full information on compressing a database in Sybase Central, see the Sybase Central online Help.


Compressing a database from the ISQL Database Tools window
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Compression utility

Compressing a database from the ISQL Database Tools window

 To use the Compression utility from the ISQL Database Tools window:

1	Select Database Tools from the Window menu.

2	Click Compress Database on the Tools list.

3	Enter the database filename (with path).

4	Click Compress, and enter a filename to use for the uncompressed database.

5	Click OK to compress the selected database file.


Compressing a database using the DBTOOL statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Compression utility

Compressing a database using the DBTOOL statement

Syntax

The syntax for the Compression utility from the ISQL DBTOOL statement is as follows:

DBTOOL COMPRESS DATABASE filename TO filename ]


The DBSHRINK command-line utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Compression utility

The DBSHRINK command-line utility

Syntax

dbshrink [switches] database-file [compressed-database-file]

Windows 3.x syntax

dbshrinw [switches] database-file [compressed-database-file]

Switch	Description
-q	Quiet mode—do not print messages
-y	Erase existing output file without confirmation
DBSHRINK reads the given database file and create a compressed database file. The compressed filename defaults to the same name as the first with an extension of CDB. The output filename (with extension) must not have the same name as the input filename (with extension).

  For more information about the command-line switches, see "Compression utility options".


Compression utility options
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Compression utility

Compression utility options

Operate quietly   Do not display messages on a window. For the DBSHRINK command-line utility, this is the -q command-line switch. This option is not available from other environments.

Operate without confirming actions   Without this option, you are prompted to confirm the replacement of an existing database file. For the DBSHRINK command-line utility, this is the -y command-line switch.


The Erase utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Erase utility

With the Erase utility, you can erase a database file or write file and its associated transaction log, or you can erase a transaction log file or transaction log mirror file. All SQL Anywhere database files, write files, and transaction log files are marked read-only to prevent accidental damage to the database or accidental deletion of the database files. Deletion of a database file that references other dbspaces does not automatically delete the dbspace files.

If you erase a database file or write 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.

You can access the Erase utility in the following ways:

♦	From Sybase Central, for interactive use under Windows 95 or NT.

♦	From the ISQL Database Tools window.

♦	From the ISQL DBTOOL statement.

♦	From the system command line, using the DBERASE command-line utility. This is useful for incorporating into batch or command files.

 Erasing a database from Sybase Central

 Erasing a database from the ISQL Database Tools window

 Erasing a database using the DBTOOL statement

 The DBERASE command-line utility

 Erase utility options


Erasing a database from Sybase Central
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Erase utility

Erasing a database from Sybase Central

 To erase a database file:

1	Open the Database Utilities folder in the left panel.

2	Double-click Erase Database in the right panel. The Erase a Database Wizard is displayed.

3	Follow the instructions in the Wizard.

For full information on erasing a database from Sybase Central, see the Sybase Central online Help.


Erasing a database from the ISQL Database Tools window
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Erase utility

Erasing a database from the ISQL Database Tools window

 To use the Erase utility from the ISQL Database Tools window:

1	Select Database Tools from the Window menu.

2	Click Erase Database or Write File on the Tools list.

3	Enter the filename (with path).

4	Click Erase, and select from the options displayed in the dialog.

5	Click OK to erase the selected files.


Erasing a database using the DBTOOL statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Erase utility

Erasing a database using the DBTOOL statement

Syntax

The syntax for the Erase utility from the ISQL DBTOOL statement is as follows:

drop database database-file [ noconfirm ]

The database-file may be a database file, write file, or transaction log file. The full filename must be specified, including extension. If a database file or write file is specified, the associated transaction log file (and mirror, if one is maintained) is also erased.


The DBERASE command-line utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Erase utility

The DBERASE command-line utility

Syntax

dberase [switches] database-file

Windows 3.x syntax

dberasew [switches] database-file

Switch	Description
-o	Output log messages to file
-q	Operate quietly—do not print messages
-y	Erase files without confirmation
The database-file may be a database file, write file, or transaction log file. The full filename must be specified, including extension. If a database file or write file is specified, the associated transaction log file (and mirror, if one is maintained) is also erased.

  For more information about the command-line switches, see "Erase utility options".


Erase utility options
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Erase utility

Erase utility options

Output log messages to file   Redirect log messages to the named file. For the DBERASE command-line utility, this is the -o option.

Operate quietly   Do not display messages on a window For the DBERASE command-line utility, this is the -q command-line switch. This option is not available from other environments.

Operate without confirming actions   Without this option, you are prompted to confirm the deletion of each file. For the DBERASE command-line utility, this is the -y command-line switch.


The Information utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Information utility

With the Information utility you can display information about a database file or write file. The database you wish to examine should not be running when you run the Information utility. The utility indicates when the database was created, the name of any transaction log file or log mirror that is maintained, the page size and other information. Optionally, it can also provide table usage statistics and details.

You can access the Information utility in the following ways:

♦	From the ISQL Database Tools window.

♦	From the ISQL DBTOOL statement.

♦	From the system command line, using the DBINFO command-line utility.

 Obtaining database information in the ISQL Database Tools window

 Obtaining database information using the DBTOOL statement

 The DBINFO command-line utility

 Information utility options


Obtaining database information in the ISQL Database Tools window
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Information utility

Obtaining database information in the ISQL Database Tools window

 To use the Information utility from the ISQL Database Tools window:

1	Select Database Tools from the Window menu.

2	Click Database Information on the Tools list.

3	Enter the database filename (with path).

4	Click Display to show information about the database.

5	Click Page Usage to show information on database pages.


Obtaining database information using the DBTOOL statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Information utility

Obtaining database information using the DBTOOL statement

Syntax

The syntax for the Information utility from the ISQL DBTOOL statement is as follows:

DBTOOL DBINFO DATABASE database-file TO output-file

   ...   [ [ WITH ] PAGE USAGE ]

   ...   USING connection-string

A database or write filename, with path, must be supplied. The database you wish to examine should not be running when you run the Information utility.


The DBINFO command-line utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Information utility

The DBINFO command-line utility

Syntax

dbinfo [switches] filename

Windows 3.x syntax

dbinfow [switches] filename

Switch	Description
-o filename	Output messages to file
-q	Suppress any messages
-u	Output page usage statistics
  For more information about the command-line switches, see "Information utility options".


Information utility options
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Information utility

Information utility options

Database file name   A database or write file name, with path, must be supplied. The database you wish to examine should not be running when you run the Information utility.

Output log messages to file   Redirect log messages to the named file. For the DBINFO command-line utility, this is the -o command-line switch.

Operate quietly   Do not display the information. The return code may still provide useful information (see "Software component return codes"). For the DBINFO command-line utility, this is the -q command-line switch. This option is only available from the command-line utility.

Page usage statistics   Information about the usage and size of all tables, including system and user-defined tables, is available as an option by using the -u command-line switch.


The Initialization utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

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:

♦	Case sensitivity or insensitivity

♦	Storage as an encrypted file

♦	Treatment of trailing blanks in comparisons

♦	The page size

♦	The collation sequence used

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.

You can access the Initialization utility in the following ways:

♦	From Sybase Central, for interactive use under Windows 95 or NT.

♦	From the ISQL Database Tools window.

♦	From the ISQL DBTOOL statement.

♦	From the system command line, using the DBINIT command-line utility. This is useful for incorporating into batch or command files.

The standalone database engine is required by the initialization utility during the initialization process.

 Creating a database in Sybase Central

 Creating a database from the ISQL Database Tools window

 Creating a database using the DBTOOL statement from within ISQL

 The DBINIT command-line utility

 Initialization utility options


Creating a database in Sybase Central
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Initialization utility

Creating a database in Sybase Central

 To create a database:

1	Open the Database Utilities folder in the left panel.

2	Double-click Create Database in the right panel. The Database Creation Wizard is displayed.

3	Follow the instructions in the Wizard.

For full information on creating a database in Sybase Central, see the Sybase Central online Help.


Creating a database from the ISQL Database Tools window
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Initialization utility

Creating a database from the ISQL Database Tools window

 To use the Initialization utility from the ISQL Database Tools window:

1	Select Database Tools from the Window menu.

2	Click Create Database on the Tools list.

3	Enter the database filename (with path).

4	Click Create, and select from the options displayed in the dialog.

5	Click OK to create the database.


Creating a database using the DBTOOL statement from within ISQL
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Initialization utility

Creating a database using the DBTOOL statement from within ISQL

Syntax

The syntax for the Initialization utility from the ISQL DBTOOL statement is as follows:

DBTOOL CREATE DATABASE filename

   ...   | [ NO [ TRANSACTION ] LOG ]   |

      | [ [ TRANSACTION ] LOG TO filename ]   |

   ...   | [ IGNORE CASE ]   |

      | [ RESPECT CASE ]   |

   ...   [ PAGE SIZE n ] [ COLLATION name ]

   ...   [ ENCRYPT ] [ TRAILING SPACES ]


The DBINIT command-line utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Initialization utility

The DBINIT command-line utility

Syntax

dbinit [switches] new-database-file

Windows 3.x syntax

dbinitw [switches] new-database-file

Switch	Description
-b	Blank padding of strings for comparisons
-c	Case sensitivity for all string comparisons
-e	Encrypt database
-g user	User name as replacement for dbo
-k	Omit Watcom SQL compatibility views SYS.SYSCOLUMNS and SYS.SYSINDEXES
-l	List available collating sequences
-m file-name	Use a transaction log mirror (default is no mirror)
-n	No transaction log
-o filename	Output messages to file
-p page-size	Set page size
-q	Quiet mode—do not print messages
-t log-name	Transaction log filename (default is database name with LOG extension)
-z col-seq	Collation sequence used for comparisons
For example, the database TEST.DB can be created with 1024 byte pages as follows:

dbinit -p 1024 test.db

  For more information about the command-line switches, see "Initialization utility options".


Initialization utility options
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Initialization utility

Initialization utility options

Ignore trailing blanks   Trailing blanks are ignored for comparison purposes, and embedded SQL programs pad strings fetched into character arrays. For example, the two strings

'Smith'

'Smith   '

would be treated as equal in a database created with trailing blanks ignored.

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, which was the only behavior supported in releases up to Watcom SQL 3.0. For the DBINIT command-line utility, this is the -b command-line switch.

Case sensitivity for all string comparisons   For databases created with this option, all values are considered to be case sensitive in comparisons and string operations.

This option is provided for compatibility with the ISO/ANSI SQL standard. The default is that all comparisons are case insensitive, which was the only behavior supported up to release Watcom SQL 3.0. For the DBINIT command-line utility, this is the -c command-line switch.

User ID and password—All databases are created with at least one user ID, DBA, with password SQL. If you specify create a database requiring case-sensitive comparisons, the DBA user ID and its password must be entered in uppercase.

Encrypt database   Encryption makes it more difficult for someone to decipher the data in your database by using a disk utility to look at the file. File compaction utilities are not able to compress encrypted database files as much as unencrypted ones. For the DBINIT command-line utility, this is the -e command-line switch.

User ID for dbo user   SQL Anywhere contains a set of system views that mimic the system tables of Sybase SQL Server. By default, the owner of these views is the user ID dbo, which is the same as the owner of the SQL Server system tables. If you already have a user ID named dbo, or you wish to use that user ID for other purposes, this option allows you to provide an alternative user ID for the owner of the SQL Server-like system views. For the DBINIT command-line utility, this is the -g command-line switch.

Omit Watcom SQL compatibility views    By default, the DBINIT command-line utility generates the views SYS.SYSCOLUMNS and SYS.SYSINDEXES for compatibility with system tables available in Watcom SQL. These views will conflict with the Sybase SQL Server compatibility views dbo.syscolumns and dbo.sysindexes if the -c case sensitivity command-line switch is not used. The -k command-line switch causes DBINIT to omit the generation of Watcom SQL compatibility views.

Use a transaction log mirror   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, SQL 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. For the DBINIT command-line utility, this is the -m command-line switch.

Do not use a transaction log   Creating a database without a transaction log is more economical on 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. For the DBINIT command-line utility, this is the -n command-line switch.

Page size   The page size for a SQL Anywhere database can be 512, 1024, 2048 or 4096 bytes, with 1024 being the default. Other values for the size will be changed to the next larger size. Large databases usually benefit from a larger page size. For the DBINIT command-line utility, this is the -p command-line switch.

Output log messages to file   Redirect log messages to the named file. For the DBINIT command-line utility, this is the -o command-line switch.

Operate quietly   Do not display messages on a window. For the DBINIT command-line utility, this is the -q command-line switch. This option is not available from other environments.

Set the transaction log filename   The transaction log is a file where the database engine logs all changes made by all users no matter what application system 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. For the DBINIT command-line utility, this is the -t command-line switch. 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.

Collating sequence or collation filename   The collation sequence is used for all string comparisons in the database.

The database is created with all collations listed in SYS.SYSCOLLATION.

If you want to use a custom collation, then you should use the Collation utility to extract the closest collation from the database, then modify the collation file and use the Initialization utility to specify the new collation. It is important to change the collation label in the custom collation file, otherwise the Initialization utility prevents the insertion of the new collation, since it will be a duplicate label.

For more information on custom collating sequences, see the chapter "Database Collations".

In order to change the collation that an existing database is using, it is necessary to unload the database, create a new database using the appropriate collation, then reload the database.

For the DBINIT command-line utility, this is the -z command-line switch. If -z is specified and names one of the collations then that collation will be used by the database. If -z is specified but does not name one of the collations, then it is assumed that the name is a filename, and the file will be opened and the collation will be parsed from the file. The specified collation will then be used by the database. If -z is not specified, then the default collation is used. Normal ASCII (binary) ordering is used for the lower 128 characters. For the upper 128 characters (also called the extended characters), characters which are accented forms 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 a letter is based upon code page 850 (multilingual code page).

The following table identifies the available collating sequence labels. All collating sequences except EBCDIC do not affect the normal ASCII character set.

Label	Explanation
437EBCDIC	(Code Page 437, EBCDIC)
437LATIN1	(Code Page 437, Latin 1)
437ESP	(Code Page 437, Spanish)
437SVE	(Code Page 437, Swedish/Finnish)
850CYR	(Code Page 850, Cyrillic)
850DAN	(Code Page 850, Danish)
850ELL	(Code Page 850, Greek)
850ESP	(Code Page 850, Spanish)
850ISL	(Code Page 850, Icelandic)
850LATIN1	(Code Page 850, Latin 1)
850LATIN2	(Code Page 850, Latin 2)
850NOR	(Code Page 850, Norwegian)
850RUS	(Code Page 850, Russian)
850SVE	(Code Page 850, Swedish/Finnish)
850TRK	(Code Page 850, Turkish)
852LATIN2	(Code Page 852, Latin 2)
852CYR	(Code Page 852, Cyrillic)
855CYR	(Code Page 855, Cyrillic)
856HEB	(Code Page 856, Hebrew)
857TRK	(Code Page 857, Turkish)
860LATIN1	(Code Page 860, Latin 1)
861ISL	(Code Page 861, Icelandic)
862HEB	(Code Page 862, Hebrew)
863LATIN1	(Code Page 863, Latin 1)
865NOR	(Code Page 865, Norwegian)
866RUS	(Code Page 866, Russian)
869ELL	(Code Page 869, Greek)
SJIS	(Japanese Shift-JIS Encoding)
EUC_JAPAN	(Japanese EUC JIS X 0208-1990 and JIS X 0212-1990 encoding)
EUC_CHINA	(Chinese GB 2312-80 Encoding)
EUC_TAIWAN	(Taiwanese Big 5 Encoding)
EUC_KOREA	(Korean KS C 5601-1992 Encoding)
UTF8	(UCS-4 Transformation Format)
List the available collating sequences   Running the DBINIT command-line utility with the -l (L) option displays a list of available collating sequences and then stops. No database is created. The list of available collating sequences is automatically presented in Sybase Central and in the ISQL Database Tools window.


The ISQL utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The ISQL utility

Syntax

isql   [switches] [isql-command]

rtsql   [switches] [isql-command]

Windows 3.x syntax

isqlw   [switches] [isql-command]

rtsqlw [switches] [isql-command]

Switch	Description
-b	Do not print banner
-c "keyword=value; ..."	Supply database connection parameters
-k	Close window when finished (RTSQL only)
-q	Quiet mode—no windows or messages
-v	Verbose—output information on commands
-x	Syntax check only—no commands executed
Description

ISQL provides the user with an interactive environment for database browsing and for sending SQL statements to SQL Anywhere.

ISQL allows you to type SQL commands, or run ISQL 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 isql-command is specified, then ISQL executes the command. The most common form uses the READ statement to execute an ISQL command file in batch mode. If no isql-command is specified, then ISQL enters the interactive mode where you can type a command into a command window.

The Windows 3.x executable name is ISQLW. You can set up Program Manager icons to start ISQLW with the same command line syntax as specified above.

RTSQL and RTSQLW are runtime SQL command processors. These programs are included in the SQL Anywhere Runtime System for Windows 3.x, 95, or NT, OS/2, or DOS. They are like ISQL except there is no interactive part; they can only run command files. By including RTSQL commands, SQL command files can be run from operating system batch or command files. RTSQL automatically loads the database engine if it is not already loaded. It unloads the database engine on exit. The command line switches are the same as those of ISQL.

Switches

-b   Do not print the identification banner when ISQL starts up.

-c "keyword=value; ..."   Specify connection parameters. See "Database connection parameters" for a description of the connection parameters. If this option is not specified, the environment variable SQLCONNECT is used. If required connection parameters are not specified, then you are presented with a dialog to enter the connection parameters.

-k   Close the window when RTSQL is finished. This switch applies only to RTSQL in Windows 3.x, Windows 95, and Windows NT.

-q   Operate quietly. ISQL does not display any information on the screen. This is only useful if a command or command file is executed when starting ISQL.

-v   Verbose output. Information about each command is displayed as it is executed (RTSQL only).

-x   Scan commands but do not execute them. This is useful for checking long command files for syntax errors.

 Commands available in ISQL

 Starting ISQL from Sybase Central


Commands available in ISQL
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The ISQL utility

Commands available in ISQL

ISQL commands are broken into the following groups:

♦	Standard SQL statements that are part of the Watcom-SQL language. These commands are further broken into two groups, the data manipulation commands and the data definition commands.

♦	Commands that are particular to ISQL and manipulate the ISQL environment.

♦	Simple commands that manipulate the data window.

ISQL Commands

CONFIGURE Statement   Activate the ISQL configuration window for displaying and changing ISQL options

CONNECT Statement   Reconnect to the database engine with a different user ID and password

DBTOOL Statement   Invoke one of the database tools

DISCONNECT Statement   Disconnect from the database engine

EXIT Statement   Leave ISQL

HELP Statement   Enter the online Help facility

INPUT Statement   Do mass input into database tables

OUTPUT Statement   Output the current query results to a file

PARAMETERS Statement   Specify the parameters to a command file

QUIT Statement   Leave ISQL

READ Statement   Execute ISQL command files

SET CONNECTION Statement   Change the active database connection

SET OPTION Statement   Set options that control the ISQL environment

SYSTEM Statement   Executes an operating system command (not available in Windows 3.x).

ISQL data window manipulation commands

The data window manipulation commands are as follows (these commands are not described in the command summary section):

CLEAR Statement   Clear the data window

DOWN [n]    Move the current query results down n lines. The default is one line.

UP [n]    Move the current query results up n lines. The default is one line.

  For more information

For detailed descriptions of SQL statements and ISQL commands, see the chapter "Watcom-SQL Language Reference".


Starting ISQL from Sybase Central
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The ISQL utility

Starting ISQL from Sybase Central

You can start ISQL from Sybase Central in the following ways:

♦	Right-click a database, and select Open ISQL from the popup menu.

♦	Right-click a table, and select View Data from the popup menu. ISQL opens with the data in the table displayed in the Data window.

♦	Right-click a stored procedure, and select Test from the popup menu. ISQL opens with a test script in the Command window.


The Log Translation utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

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, for interactive use under Windows 95 or NT.

♦	From the ISQL Database Tools window.

♦	From the ISQL DBTOOL statement.

♦	From the system command line, using the DBTRAN command-line utility. This is useful for incorporating into batch or command files.

 Translating a transaction log in Sybase Central

 Translating a transaction log from the ISQL Database Tools window

 Translating a transaction log using the DBTOOL statement

 The DBTRAN command-line utility

 Log translation utility options


Translating a transaction log in Sybase Central
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Log Translation utility

Translating a transaction log in Sybase Central

 To translate a transaction log into a command file:

1	Open the Database Utilities folder in the left panel.

2	Double-click Translate Log in the right panel. The Translate Log Wizard is displayed

3	Follow the instructions in the Wizard.


Translating a transaction log from the ISQL Database Tools window
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Log Translation utility

Translating a transaction log from the ISQL Database Tools window

 To use the Log Translation utility from the ISQL Database Tools window:

1	Select Database Tools from the Window menu.

2	Click Translate Transaction Log to SQL on the Tools list.

3	Enter the transaction log filename (with path).

4	Click Translate, and select from the options in the dialog.

5	Click OK to translate the selected transaction log file to a SQL command file.


Translating a transaction log using the DBTOOL statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Log Translation utility

Translating a transaction log using the DBTOOL statement

Syntax

The syntax for the Log Translation utility from the ISQL DBTOOL statement is as follows:

DBTOOL TRANSLATE [ TRANSACTION ] LOG FROM logname

...   [ TO sqlfile ] [ WITH ROLLBACKS ]

...   | [ USERS u1, u2, ... , un ]   |

   | [ EXCLUDE USERS u1, u2, ... , un ]   |

...   [ LAST CHECKPOINT ] [ ANSI ] [ NOCONFIRM ]


The DBTRAN command-line utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Log Translation utility

The DBTRAN command-line utility

Syntax

dbtran [switches] transaction-log [sql-log]

Windows 3.x syntax

dbtranw [switches] transaction-log [sql-log]

Switch	Description
-a	Include rollback transactions in output
-f	Output from most recent transaction
-j date/time	Output from checkpoint prior to given date
-r	Remove uncommitted transactions (default)
-s	Produce ANSI standard SQL UPDATE transactions
-t	Include trigger-generated transactions in output
-u userid,...	Translate transactions for listed users
-x userid,...	Exclude transactions for listed users
-y	Replace file without confirmation
-z	Include trigger-generated transactions as comments
The sql-log filename defaults to the transaction log name with the extension SQL.

When the DBTRAN command-line utility is run, it displays the earliest log offset contained in the transaction log being translated. This can be an effective method for determining the order in which multiple log files where generated.

  For more information about log offset numbers please see "The SQL Remote message tracking system"

  For more information about the command-line switches, see "Log translation utility options".


Log translation utility options
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Log Translation utility

Log translation utility options

Include uncommitted transactions   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. For the DBTRAN command-line utility, this is the -a command-line switch.

Translate from last checkpoint only   Only those transactions completed since the last checkpoint are translated. For the DBTRAN command-line utility, this is the -f command-line switch.

Output from checkpoint prior to given date   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 of the given date. If the date is omitted, the current day is assumed. The following is an acceptable format for the date and time: "YY/MMM/DD HH:MM". For the DBTRAN command-line utility, this is the -j date/time command-line switch.

Do not include uncommitted transactions   Remove any transactions that were not committed For the DBTRAN command-line utility, this is the -r command-line switch, and the default operation.

Generate ANSI standard SQL UPDATE   For cases where there is no primary key or unique index on a table, the Translation utility generates UPDATE statements with a non-standard FIRST keyword, in case of duplicate rows. The ANSI standard UPDATE flag does not output this keyword. For the DBTRAN command-line utility, this is the -s command-line switch.

Include transactions generated by triggers   By default, actions carried out by triggers are not included in the command file. If the matching trigger is in place in the database, then when the command file is run against the database, the trigger will carry out the actions automatically. Trigger actions should be included in the case that the matching trigger does not exist in the database against which the command file is to be run. For the DBTRAN command-line utility, this is the -t command-line switch.

Translate transactions for listed users only   For the DBTRAN command-line utility, this is the -u command-line switch.

Translate transactions except for listed users   For the DBTRAN command-line utility, this is the -x command-line switch.

Operate without confirming actions    Without this option, you are prompted to confirm the replacement of an existing command file. For the DBTRAN command-line utility, this is the -y command-line switch.

Include transactions generated by triggers as comments only   Transactions generated by triggers will be included only as comments in the output file. For the DBTRAN command-line utility, this is the -z command-line switch.


The Open Server Gateway
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Open Server Gateway

The SQL Anywhere Open Server enables Sybase dblib and ctlib applications to connect to SQL Anywhere databases.

Syntax

dbos50 [switches] [open-server-name]

Switch	Description
-d database-name	Name of database for connections
-c 5501	Release 5.501 data type mapping compatibility
-e engine-name	Name of engine or client for connections
-o log_file	Output messages to file
-p	Run in non-preemptive mode
-v	Verbose operation (extended messages)
-w	React to Warnings as Errors
Description

The SQL Anywhere Open Server enables Sybase dblib and ctlib applications to connect to SQL Anywhere databases.

For SQL Anywhere databases participating in a Replication Server installation, SQL Anywhere Open Server is required at primary and replicate sites to enable Replication Server to connect to the database. At a SQL Anywhere replicate site, Replication Server must connect in order to apply changes to the database. At a SQL Anywhere primary site, Replication Server must connect for the materialization step and if asynchronous procedure calls are being carried out.

The default Open Server name is SQLAny. When the Open Server Gateway is being used for Replication Server, the Open Server name must be the same as the SQL Anywhere server name (-e option) that it provides connections for.

Switches

-d database-name   Sets the database for connections. Connections to SQL Server are made to the server, while connections to SQL Anywhere are made to an individual database. The -d switch allows Open Server Gateway to support SQL Server connection events. If no -d switch is provided, the Open Server uses the first active database on the specified engine or client for all connections.

-c 5501   The mapping of data types between Open Client applications and SQL Anywhere was modified in release 5.502. The -c switch is provided for Open Client applications requiring the older data type mapping behavior (available in releases 5.501 and earlier). Other forms of this switch include: -c 5500, -c 5.501, -c 5.500.

  For more information about the data type mapping of Open Server Gateway, see "Data type mappings".

-e server-name   Sets the SQL Anywhere server name for connections. Connections to SQL Server are made to the server, while connections to SQL Anywhere are made to an individual database. The -d switch allows Open Server Gateway to support SQL Server connection events. If no -e switch is provided, the Open Server looks for a running engine or client and uses the first engine or client it finds for all connections.

-o logfile   Name the log file to which messages are output. The default name for the log file is the server name with extension .WOS.

-p   Run in non-preemptive mode. In non-preemptive mode the Open Server processes commands serially rather than concurrently.

-v   With the -v switch set, the messages sent to the log file are also sent to the current command-line window.

-w   With the -w switch set, the Open Server reacts to warnings as if they were errors, stopping execution. This may be useful during development, especially if the application is to run against other Open Servers also.


The Open Server Information utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Open Server Information utility

Syntax

dbosinfo [switches]

Switch	Description
-s server	Open Server to return information on
-u userid	Connection username
-p password	Connection password
-v	Verbose operation
Description

The DBOSINFO command-line utility returns information about a Open Server Gateway. Currently, the only information returned is the TDS version.

Switches

-S server   The Open Server to return information on. The Open Server name is declared on the DBOS50 command line, and corresponds to an entry in the list of Open Servers maintained by SQLEDIT .

-U userid   A SQL Anywhere user ID on a database being supported by the Open Server.

-P password   The SQL Anywhere connection password corresponding to the user ID provided in the -U command line.

-v   Extra messages are sent to the window.


The Open Server Stop utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Open Server Stop utility

Syntax

dbosstop [switches]

Switch	Description
-s server	Open Server to stop
-u userid	Connection username
-p password	Connection password
-x password	Stopping password
-q	Operate quietly
-v	Verbose operation
Description

The DBOSSTOP command-line utility stops a Open Server Gateway.

Switches

-S server   The Open Server to stop. The Open Server name is declared on the DBOS50 command line, and corresponds to an entry in the list of Open Servers maintained by SQLEDIT .

-U userid   A SQL Anywhere user ID on a database being supported by the Open Server.

-P password   The SQL Anywhere connection password corresponding to the user ID provided in the -U command line.

-x password   An additional password for DBOSSTOP. This is currently set permanently to thx1138.

-q   Operate quietly. No messages are sent to the log file.

-v   Extra messages are sent to the window.


The REBUILD batch or command file
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The REBUILD batch or command file

Syntax

rebuild old-database new-database [dba-password]

Description

This DOS or Windows NT batch file, OS/2 command file, or QNX script uses DBUNLOAD to rebuild old-database into new-database. This is a simple script, but it helps document and automate the rebuilding process. Both database names should be specified without extensions. An extension of DB. will automatically be added.

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 ISQL commands with the default command line options. If you need different options, you will need to run the three steps separately.


The SQL Remote Database Extraction utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The SQL Remote Database Extraction utility

You can access the remote database extraction utility in the following ways:

♦	From Sybase Central, for interactive use under Windows 95 or NT.

♦	From the system command line, using the DBXTRACT command-line utility. This is useful for incorporating into batch or command files.

By default, the extraction utility runs at isolation level zero. If you are extracting a database from a running 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.

Objects owned by dbo

The dbo user ID owns a set of SQL Server-compatible system objects in a SQL Anywhere database.

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.

Extraction utility limitations—The extraction utility is not designed to create a flawless reload script under all circumstances, but can produce a script which can be modified to the user's needs. An inconsistent database could still be created, if for example, a view referencing non-replicated tables is extracted.

 Extracting a remote database in Sybase Central

 The DBXTRACT command-line utility

 Extraction utility options


Extracting a remote database in Sybase Central
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The SQL Remote Database Extraction utility

Extracting a remote database in Sybase Central

 To extract a remote database from a running database:

1	Connect to the database.

2	Right-click the database and click Extract Database in the popup menu.

3	Follow the instructions in the wizard.

 To extract a remote database from a database file or a running database as follows::

1	Open the Database Utilities folder in the left panel.

2	Double-click Extract a Database in the right panel.

3	Follow the instructions in the wizard.

For full information on extracting a remote database in Sybase Central, see the Sybase Central online Help.


The DBXTRACT command-line utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The SQL Remote Database Extraction utility

The DBXTRACT command-line utility

Syntax

dbxtract [switches] directory subscriber

Windows 3.x syntax

dbxtracw [switches] directory subscriber

Switch	Description
-b	Do not start subscriptions
-c "keyword=value; ..."	Supply database connection parameters
-d	Unload data only
-f	Extract fully qualified publications
-g .user	Specify user name as replacement for dbo
-j nnn	Repeated unload of 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
-r .file	Specify name of generated reload ISQL
	command file (default "RELOAD.SQL")
-u	Unordered data
-v	Verbose messages
-xf	Exclude foreign keys
-xp	Exclude stored procedures
-xt	Exclude triggers
-xv	Exclude views
-y	Overwrite command file without confirmation
Description

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.

Inconsistent databases

Extraction utility limitations—The extraction utility is not designed to create a flawless reload script under all circumstances, but can produce a script which can be modified to the user's needs. An inconsistent database could still be created, if for example, a view referencing non-replicated tables is extracted.

  For more information about the command-line switches, see "Extraction utility options".


Extraction utility options
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The SQL Remote Database Extraction utility

Extraction utility options

Do not start subscriptions automatically   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. For the DBXTRACT command-line utility, this is the -b switch.

Connection parameters   For a description of the connection parameters, see "Database connection parameters". If the connection parameters are not specified, connection paremeters from the SQLCONNECT environment variable are used, if set. The user ID should have DBA authority to ensure that the user has permissions on all the tables in the database.

For the DBXTRACT command-line utility, this is the -c command-line switch. For example, the following statement extracts a database for remote user ID joe_remote from the sademo database running on the sample_server server, connecting as user ID DBA with password SQL. The data is unloaded into the C:\UNLOAD directory.

dbxtract -c "eng=sample_server;dbn=sademo;

uid=dba;pwd=sql" c:.extract joe_remote

Unload the data only   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. For the DBXTRACT command-line utility, this is the -d switch.

Extract fully qualified publications   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. For the DBXTRACT command-line utility, this is the -f switch.

Repeated unload of view creation statements   If your database contains view definitions that are dependent on each other, you can use this option to avoid failure in reloading the views into a database. The option causes view creation statements to be unloaded multiple times, as specified by the count entered. This count should be small, and should correspond to the number of levels of view dependency. For the DBXTRACT command-line utility, this is the -j command-line switch.

Perform extraction at a specified isolation level   The default setting is an isolation level of zero. If you are extracting a database from a running 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. For the DBXTRACT command-line utility, this is the -l switch.

Unload the schema definition only   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. For the DBXTRACT command-line utility, this is the -n switch.

Output messages to file   For the DBXTRACT command-line utility, this is the -o switch.

Escape character   The default escape character (\) can be replaced by another character using this option. For the DBXTRACT command-line utility, this is the -p command-line switch.

Operate quietly   Display no messages except errors. For the DBXTRACT command-line utility, this is the -q command-line switch. This option is not available from other environments.

Reload filename   The default name for the reload command file is RELOAD.SQL in the current directory. For the DBXTRACT command-line utility, this is the -r switch.

Output the data unordered   By default the data in each table is ordered by primary key. Unloads are quicker with the -u switch, but loading the data into the remote database is slower. For the DBXTRACT command-line utility, this is the -u switch.

Verbose mode   The name of the table being unloaded and the number of rows unloaded are displayed. The SELECT statements being used to extract data from tables is also displayed, which can be useful because the SELECT statements have WHERE clauses that can lead to slow extracts, such as when indexes have not been created. For the DBXTRACT command-line utility, this is the -v switch.

Exclude foreign key definitions   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. For the DBXTRACT command-line utility, this is the -xf switch.

Exclude stored procedure   Do not extract stored procedures from the database. For the DBXTRACT command-line utility, this is the -xp switch.

Exclude triggers   Do not extract triggers from the database. For the DBXTRACT command-line utility, this is the -xt switch.

Exclude views   Do not extract views from the database. For the DBXTRACT command-line utility, this is the -xv switch.

Operate without confirming actions   Without this option, you are prompted to confirm the replacement of an existing command file. For the DBXTRACT command-line utility, this is the -y switch.


The SQL Remote Message Agent
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The SQL Remote Message Agent

Syntax

dbremote [switches] [ directory ]

Windows 3.x syntax

dbremotw [switches] [ directory ]

Switch	Description
-a	Do not apply received transactions
-b	Run in batch mode
-c  "keyword=value; ..."	Supply database connection parameters
-f minutes	Receive message polling frequency (default is one minute)
-k	Close window on completion
-l length	Maximum message length
-m size	Maximum amount of memory to be used by DBREMOTE for building messages.
-o file	Output messages to file
-p	Do not purge messages
-r	Receive only
-s	Send only
-t	Replicate all triggers
-u	Process only backed up transactions
-v	Verbose operation
-x	Rename transaction log
Description

The messaging agent sends and applies messages for SQL Remote replication, and maintains the message tracking system to ensure message delivery.

The user ID in the Message Agent command line must have either REMOTE DBA or DBA authority.

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.

A database can have only one instance of the messaging agent connecting to it at a time. However, multiple instances of the messaging agent can connect to a single database engine or server hosting multiple databases, provided only one messaging agent connects to one database.

For information on REMOTE DBA authority,  see "The Message Agent and replication security". For information on log management in SQL Remote, see "Transaction log and backup management for SQL Remote".

Switches

-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 flag can help detect problems with incoming messages. Used without -p, this flag 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 "keyword=value; ..."    Specify connection parameters. See "Database connection parameters" for a description of the connection parameters. 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:\SQLANY50\SADEMO.DB, connecting with user ID dba and password sql:

dbremote -c "uid=dba;pwd=sql;dbf=c:\sqlany50\sademo.db"

The DBREMOTE command-line utility 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".

-f minutes   Sets the frequency of incoming message checking when DBREMOTE is used in continuous mode (not batch mode). Specifies in minutes how often the source of messages is polled. Values greater than the SEND EVERY option specified in the GRANT REMOTE SQL statement cause DBREMOTE to check for incoming messages once after each send cycle. If this value is not set, a default polling frequency of one minute is used.

-k   Close window on completion. This flag is valid for Windows and Windows NT only.

-l length   Specifies the maximum length of message to be sent, in bytes. The default is 51200 (50K). Longer transactions are split into more than one message.

-m size   Specifies a maximum amount of memory to be used by DBREMOTE for building messages. When the memory usage is exceeded, messages are flushed (before being full). The allowed size can be specified as n (in bytes), nK, or nM. The default is 2048K (2M).

This is provided for customers considering a single consolidated database for thousands of remote databases.

-o file   Append output to a log file. Default is to send output to the screen.

-p   Process the messages without purging them.

-r   Receive messages only.

-s   Send messages only.

-t    All trigger actions are replicated. If you do use this switch, 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.

-u   Process only transactions that have been backed up. This switch prevents DBREMOTE from processing transactions contained in the live transaction log. Transactions in the live, or active transaction log are not processed until that log file is backed up. Outgoing transactions and confirmation of incoming messages are only processed for those transactions that are not in the live transaction log.

-v   Verbose output. This switch displays the SQL statements contained in the messages to the screen and, if the -o switch is used, to a log file.

-x   Renames transaction log after it has been scanned for outgoing messages. Since replication can have the effect of backing up a database, in many cases this switch eliminates the need to run DBBACKUP on the remote computer (or renaming the transaction log when the engine is shut down).

Registry settings

SQL Remote uses several registry settings (in Windows 95 and NT) or initialization file settings (Windows 3.x and OS/2) to control aspects of message link behavior.

In the registry, the settings are stored in the Current User, under Software [image] Sybase [image] SQL Anywhere [image] Sybase SQL Anywhere 5.0 [image] SQL Remote. In Windows 3.x and OS/2, they are stored in the SQLANY.INI initialization file.

  For a listing of registry settings, see "Message link control parameters".


The Stop utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Stop utility

The Stop utility stops a SQL Anywhere standalone engine, network server, or SQL Anywhere Client.

All memory used by the database engine is returned to the system for use by other applications.

The Stop utility is a command-line utility only. In Windowing environments, you can stop a database engine or server by clicking Close on the engine window or choosing Exit from the File menu on the server window.

 The DBSTOP command-line utility

 Stop utility options


The DBSTOP command-line utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Stop utility

The DBSTOP command-line utility

Syntax

dbstop [switches] { name | CLIENT }

Windows 3.x syntax

dbstopw [switches] { name | CLIENT }

Parameter	Description
-q	Quiet mode—do not print messages
-s "keyword=value; ..."	Supply database connection parameters
-x	Do not stop if there are active connections
name	Engine or server name
In DOS, it is not necessary to specify a name, because only one database engine or client can be running.

In QNX, DBSTOP can shut down a server on any node on the network. The name is necessary to specify the name of the server you wish to stop.

The DBSTOP command is not necessary after the database engine has been started by ISQL. ISQL automatically unloads the database engine when it disconnects.

DBSTOP CLIENT stops the SQL Anywhere Client only.

  For more information about the command-line switches, see "Stop utility options".


Stop utility options
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Stop utility

Stop utility options

-q   Operate quietly. Do not print a message if the database was not running.

-s   When stopping a database server, you must supply a connection string with a user ID that has permissions to stop the server or engine. By default, DBA permission is required on the database server, and all users can shut down a standalone engine, but the -gk switch on the engine or server can be used to change this.

$   For a description of the connection parameters, see "Database connection parameters".To shut down a database server, the connection string must include an AGENT parameter in addition to the usual connection parameters.  AGENT must be set to the value SERVER to shut down a server. A sample command line is:

dbstop -s "uid=dba;pwd=sql;

   agent=server;unconditional=true"

-x   Do not stop the engine if there are still active connections to the engine.

QNX switch

-p password   Specify a password to unlock the server. If the server's keyboard is locked and no password is specified or the specified password is incorrect, then the server will not shut down.


The Transaction Log utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

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 a 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 or with write files. The database engine must not be running on that database when the transaction log filename is changed (an error message is displayed if it is).

You can access the Transaction Log utility in the following ways:

♦	From Sybase Central, for interactive use under Windows 95 or NT

♦	From the ISQL Database Tools window.

♦	From the ISQL DBTOOL statement.

♦	From the system command line, using the DBLOG command-line utility

 Changing a log file name from Sybase Central

 Changing a log file name from the ISQL Database Tools window

 Changing a log filename from the DBTOOL statement

 The DBLOG command-line utility

 Transaction log utility options


Changing a log file name from Sybase Central
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Transaction Log utility

Changing a log file name from Sybase Central

 To change a transaction log file name:

1	Open the Database Utilities folder in the left panel.

2	Double-click Change Log File in the right panel. The Transaction Log Wizard is displayed

3	Follow the instructions in the Wizard.

For full information on changing a log file name from Sybase Central, see the Sybase Central online Help.


Changing a log file name from the ISQL Database Tools window
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Transaction Log utility

Changing a log file name from the ISQL Database Tools window

 To use the Translation Log utility from the ISQL Database Tools window to change a log filename:

1	Select Database Tools from the Window menu.

2	Click Change Transaction Log Name on the Tools list.

3	Enter the database filename (with path).

4	Click Change, and select from the options on the dialog.

5	Click OK to change the name of the transaction log, or to run without a transaction log.


Changing a log filename from the DBTOOL statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Transaction Log utility

Changing a log filename from the DBTOOL statement

Syntax

DBTOOL ALTER DATABASE name

...     NO [ TRANSACTION ] LOG

   | SET [ TRANSACTION ] LOG TO filename

You can rename the database filename as well as the transaction log name from the DBTOOL statement.


The DBLOG command-line utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Transaction Log utility

The DBLOG command-line utility

Syntax

dblog [switches] database-file

Windows 3.x syntax

dblogw [switches] database-file

Switch	Description
-g n	Sets the 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
-m mirror-name	Set transaction log mirror name
-n	No longer use a transaction log
-o	Output messages to file
-q	Quiet mode—do not print messages
-r	No longer use a transaction log mirror
-t log-name	Set transaction log name
  For more information about the command-line switches, see "Transaction log utility options".


Transaction log utility options
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Transaction Log utility

Transaction log utility options

Set the generation number   This option is for use when using the SQL Anywhere Log Transfer Manager in order 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 on generation numbers and dbcc, see your Replication Server documentation. For the DBLOG command-line utility, this is the -g command-line switch.

Ignore the LTM truncation offset   This option is for use when using the SQL Anywhere Log Transfer Manager in order to participate in a Replication Server installation. It performs the same function as the following Replication Server function:

dbcc settrunc( 'ltm', 'gen_id', n ).

For information on dbcc, see your Replication Server documentation. For the DBLOG command-line utility, this is the -il command-line switch.

Ignore the SQL Remote truncation offset   This option is for use when using the SQL Anywhere Log Transfer Manager in order to participate in a Replication Server installation and a SQL Remote installation. It resets the offset that is kept for the purposes of the DELETE_OLD_LOGS option, allowing transaction logs to be deleted when they are no longer needed. For the DBLOG command-line utility, this is the -ir command-line switch.

Set the name of the transaction log mirror file   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 filename as its transaction log mirror. For the DBLOG command-line utility, this is the -m command-line switch.

No longer use a transaction log   Stop using a transaction log. Without a transaction log, the database will no longer be able to participate in data replication or use the transaction log in data recovery. For the DBLOG command-line utility, this is the -n command-line switch.

Output log messages to file   Redirect log messages to the named file. For the DBLOG command-line utility, this is the -o command-line switch.

Operate quietly   Do not display messages on a window. For the DBLOG command-line utility, this is the -q command-line switch. This option is not available from other environments.

No longer use a transaction log mirror   For databases maintaining a mirrored transaction log, this option changes their behavior to maintain only a single transaction log. For the DBLOG command-line utility, this is the -r command-line switch.

Set the name of the transaction log file   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 filename as its transaction log. For the DBLOG command-line utility, this is the -t command-line switch.


The Uncompression utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Uncompression utility

With the Uncompression utility you can expand a compressed database file created by the Compression utility. The Uncompression utility reads the given compressed database file and creates an uncompressed database file.

The Uncompression utility does not uncompress files other than the main database file (dbspace files).

You can access the Uncompression utility in the following ways:

♦	From Sybase Central, for interactive use under Windows 95 or NT.

♦	From the ISQL Database Tools window.

♦	From the ISQL DBTOOL statement.

♦	From the system command line, using the DBEXPAND command-line utility. This is useful for incorporating into batch or command files.

 Uncompressing a database in Sybase Central

 Uncompressing a database from the ISQL Database Tools window

 Uncompressing a database using the DBTOOL statement

 The DBEXPAND command-line utility

 Uncompression utility options


Uncompressing a database in Sybase Central
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Uncompression utility

Uncompressing a database in Sybase Central

 To uncompress a compressed database file:

1	Open the Database Utilities folder in the left panel.

2	Double-click Uncompress Database in the right panel. The Uncompress Wizard is displayed.

3	Follow the instructions in the Wizard.

For full information on uncompressing a database in Sybase Central, see the Sybase Central online Help.


Uncompressing a database from the ISQL Database Tools window
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Uncompression utility

Uncompressing a database from the ISQL Database Tools window

 To use the Uncompression utility from the ISQL Database Tools window:

1	Select Database Tools from the Window menu.

2	Click Uncompress Database on the Tools list.

3	Enter the database filename (with path).

4	Click Uncompress, and enter a filename to use for the uncompressed database.

5	Click OK to uncompress the selected database file.


Uncompressing a database using the DBTOOL statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Uncompression utility

Uncompressing a database using the DBTOOL statement

Syntax

The syntax for the Uncompression utility from the ISQL DBTOOL statement is as follows:

DBTOOL UNCOMPRESS DATABASE compressed-database-file

   ...   [ TO filename ] [ NOCONFIRM ]


The DBEXPAND command-line utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Uncompression utility

The DBEXPAND command-line utility

Syntax

dbexpand [switches] compressed-database-file [database-file]

Windows 3.x syntax

dbexpanw [switches] compressed-database-file [database-file]

Switch	Description
-q	Operate quietly—do not print messages
-y	Erase existing output file without confirmation
The input filename extension defaults to CDB. The output filename (with extension) must not have the same name as the input filename (with extension).

  For more information about the command-line switches, see "Uncompression utility options".


Uncompression utility options
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Uncompression utility

Uncompression utility options

Output log messages to file   Redirect log messages to the named file. For the DBEXPAND command-line utility, this is the -o option.

Operate quietly   Do not display messages on a window. For the DBEXPAND command-line utility, this is the -q command-line switch. This option is not available from other environments.

Operate without confirming actions   Without this option, you are prompted to confirm the replacement of an existing database file. For the DBEXPAND command-line utility, this is the -y command-line switch.


The Unload utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Unload utility

With the Unload utility you can unload a database and put data files into a set of files in a named directory. The Unload utility creates the ISQL command file RELOAD.SQL to rebuild your database from scratch. It also unloads all of the data in each of your tables in comma delimited format into files in the specified directory. Binary data is properly represented with escape sequences.

You can access the Unload utility in the following ways:

♦	From Sybase Central, for interactive use under Windows 95 or NT.

♦	From the ISQL Database Tools window.

♦	From the ISQL DBTOOL statement.

♦	From the system command line, using the DBUNLOAD command-line utility. This is useful for incorporating into batch or command files.

The Unload utility should be run from a DBA user ID. This is the only way you can be sure of having privileges to unload all the data. Also, the RELOAD.SQL file should be run from the DBA user ID. (Usually it will be run on a new database where the only user ID is DBA with password SQL.)

Objects owned by dbo

The dbo user ID owns a set of SQL Server-compatible system objects in a SQL Anywhere database.

The Unload 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 Unload utility, and so these objects are preserved.

 Unloading a database from Sybase Central

 Unloading a database from the ISQL Database Tools window

 Unloading a database from the DBTOOL statement

 The DBUNLOAD command-line utility

 Unload utility options


Unloading a database from Sybase Central
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Unload utility

Unloading a database from Sybase Central

 To unload a running database:

1	Connect to the database.

2	Right-click the database and click Unload in the popup menu. The Unload Database Wizard is displayed.

3	Follow the instructions in the Wizard.

 To unload a database file or a running database:

1	Open the Database Utilities folder in the left panel.

2	Double-click Unload Database in the right panel. The Unload Database Wizard is displayed.

3	Follow the instructions in the Wizard.

For full information on unloading a database from Sybase Central, see the Sybase Central online Help.


Unloading a database from the ISQL Database Tools window
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Unload utility

Unloading a database from the ISQL Database Tools window

 To use the Unload utility from the ISQL Database Tools window:

1	Select Database Tools from the Window menu.

2	Click Unload Database on the Tools list.

3	Enter a user ID and password to use when connecting to the database.

4	For a running database, enter a database name and server name (if more than one is running). For a database file, enter the filename (with path) and optionally a start line to specify command-line switches for the database engine or SQL Anywhere Client.

5	Click Unload, and enter a filename to use for the command file and a directory in which to hold the data. Select from the other options in the dialog.

6	Click OK to unload the database.


Unloading a database from the DBTOOL statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Unload utility

Unloading a database from the DBTOOL statement

Syntax

The syntax for the Unload utility from the ISQL DBTOOL statement is as follows:

DBTOOL UNLOAD TABLES TO directory

...   [ RELOAD FILE TO filename ]

...   [ DATA ]

   | [ SCHEMA ]

...   [ UNORDERED ] [ VERBOSE ] USING connection-string


The DBUNLOAD command-line utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Unload utility

The DBUNLOAD command-line utility

Syntax

dbunload [switches] directory [ table-name-list ]

Windows 3.x syntax

dbunloaw [switches] directory [ table-name-list ]

Switch	Description
-c "keyword=value; ..."	Supply database connection parameters
-d	Unload data only
-e	No data output for listed tables
-g userid	Specify user name as replacement for dbo
-i	Data output for listed tables only
-j nnn	Repeated unload of view creation statements
-n	No data—schema definition only
-p	Escape character for external unloads
-q	Quiet mode—no windows or messages
-r reload-file	Specify name and directory of generated reload ISQL command file (default RELOAD.SQL)
-u	Unordered data
-v	Verbose messages
-x	External unload (when client and server are on different machines)
-y	Replace command file without confirmation
In the default mode the directory used by DBUNLOAD to hold the data is relative to the database engine or 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 the -x switch is used, the directory is relative to the current directory of the user. The RELOAD.SQL command file is always relative to the current directory of the user, regardless of whether -x is used.

If no list of tables is supplied, the whole database is unloaded. If a list of tables is supplied, only those tables are unloaded.

  For more information about the command-line switches, see "Unload utility options".


Unload utility options
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Unload utility

Unload utility options

Connection parameters   For a description of the connection parameters, see "Database connection parameters". If the connection parameters are not specified, connection paremeters from the SQLCONNECT environment variable are used, if set. The user ID should have DBA authority to ensure that the user has permissions on all the tables in the database.

For the DBUNLOAD command-line utility, this is the -c command-line switch. For example, the following statement unloads the sademo 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=sademo;uid=dba;pwd=sql" c:\unload

Unload data only   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. For the DBUNLOAD command-line utility, this is the -d command-line switch.

No data output for listed tables   For the DBUNLOAD command-line utility, this is the -e command-line switch. This is not accessible from other environments. By default, the optional table-list defines the tables to be unloaded. If you wish to unload almost all the tables in the database, the -e command-line switch unloads all tables except the specified tables.

User ID for dbo user   SQL Anywhere contains a set of system views that mimic the system tables of Sybase SQL Server. By default, the owner of these views is the user ID dbo, which is the same as the owner of the SQL Server system tables, but you may have configured this differently when creating or upgrading your database. If the SQL Server-compatibility system views in your database are owned by a user other than dbo, specify that user ID in this option. Views and procedures owned by the user ID you specify are not unloaded. For the DBUNLOAD command-line utility, this is the -g command-line switch.

Data output for listed tables only   For the DBUNLOAD command-line utility, this is the -i command-line switch. This is not accessible from other environments. This switch is the default option, and causes only the supplied table-list to be unloaded.

Repeated unload of view creation statements   If your database contains view definitions that are dependent on each other, you can use this option to avoid failure in reloading the views into a database. The option causes view creation statements to be unloaded multiple times, as specified by the count entered. This count should be small, and should correspond to the number of levels of view dependency. For the DBUNLOAD command-line utility, this is the -j command-line switch.

Unload schema definition only   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. For the DBUNLOAD command-line utility, this is the -n command-line switch.

Escape character   The default escape character (\) for external unloads (DBUNLOAD -x switch) can be replaced by another character using this option. For the DBUNLOAD command-line utility, this is the -p command-line switch. This option is not available from other environments.

Operate quietly   Display no messages except errors. For the DBUNLOAD command-line utility, this is the -q command-line switch. This option is not available from other environments.

Specify reload filename   Modify the name and directory of the generated reload ISQL command file. The default is RELOAD.SQL in the current directory. For the DBUNLOAD command-line utility, this is the -r command-line switch.

Output the data unordered   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. For the DBUNLOAD command-line utility, this is the -u command-line switch.

Enable verbose mode   The table name of the table currently being unloaded and how many rows have been unloaded is displayed. For the DBUNLOAD command-line utility, this is the -v command-line switch. This option is not available from other environments.

Use external unloading   The Unload utility uses the UNLOAD TABLE statement by default. If the external unloading option is specified, the ISQL OUTPUT statement is used to extract the data, and the generated reload command file uses the INPUT INTO statement to reload the data. For the DBUNLOAD command-line utility, this is the -x command-line switch.

The default mode is faster than the external unloading mode. However, in the default mode the directory used by the Unload utility to hold the data is relative to the database server, not to the current directory of the user. The RELOAD.SQL command file is always relative to the current directory of the user, regardless of whether external unloading is used.

For more information on filenames and paths for the Unload utility, see "UNLOAD TABLE statement".

Operate without confirming actions   Without this option, you are prompted to confirm the replacement of an existing command file. For the DBUNLOAD command-line utility, this is the -y command-line switch.

Rebuilding a database

To unload a database, start the database engine with your database, and run the Unload utility with the DBA user ID and password.

To reload a database, you need to create a new database and then run the generated RELOAD.SQL command file through ISQL or RTSQL.

In Windows 95 and Windows NT, there is a file (REBUILD.BAT) included with SQL Anywhere that automates the unload and reload process. In Windows 3.x, rebuilding can be done from the ISQL Database Tools window.

In DOS, OS/2, Windows 95 and NT, and QNX, there is a file (REBUILD.BAT, REBUILD.CMD, or rebuild) included with SQL Anywhere that automates the unload and reload process. In Windows 3.x, rebuilding can be done from the ISQL Database Tools window.


The Upgrade utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Upgrade utility

The Upgrade utility upgrades a database created with Watcom SQL 3.2 or Watcom SQL 4.0 to the SQL Anywhere 5.0 format. While SQL Anywhere 5.0 does run against a database created with Watcom SQL 3.2 or Watcom SQL 4.0, some of the features introduced since the version that created the database are unavailable unless the database is upgraded.

For people switching from release 3.2 or 4.0 to the current release, the Upgrade utility upgrades their databases without having to unload and reload them.

If you wish 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, for interactive use under Windows 95 or NT.

♦	From the system command-line, using the DBUPGRAD command-line utility.

 Upgrading a database from Sybase Central

 Upgrading databases too old for the Upgrade utility

 The DBUPGRAD command-line utility

 Upgrade utility options


Upgrading a database from Sybase Central
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Upgrade utility

Upgrading a database from Sybase Central

 To upgrade a database:

1	Open the Database Utilities folder in the left panel.

2	Double-click Uprade Database in the right panel. The Upgrade Database Wizard is displayed.

3	Follow the instructions in the Wizard.

  For full information on upgrading a database from Sybase Central, see the Sybase Central online Help.


Upgrading databases too old for the Upgrade utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Upgrade utility

Upgrading databases too old for the Upgrade utility

 To upgrade a database created with a version of SQL Anywhere that is too old to be upgraded:

1	Unload the database using the Unload utility.

2	Create a database with the name you wish to use for the upgraded version, using the Initialization utility.

3	Connect to the new database from ISQL as the DBA user ID, and read the reaload.sql command file to build the new database.


The DBUPGRAD command-line utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Upgrade utility

The DBUPGRAD command-line utility

Syntax

dbupgrad [switches]

Windows 3.x syntax

dbupgrdw [switches]

Switch	Description
-c "keyword=value; ..."	Supply database connection parameters
-g userid	User ID to use as replacement for dbo
-k	Close window on completion
-q	Quiet mode—no windows or messages
  For more information about the command-line switches, see "Upgrade utility options".


Upgrade utility options
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Upgrade utility

Upgrade utility options

Connection parameters   For a description of the connection parameters, see "Database connection parameters". If the connection parameters are not specified, connection paremeters from the SQLCONNECT environment variable are used, if set. The user ID must have DBA authority.

For the DBUPGRAD command-line utility, this is the -c command line switch. For example, the following command upgrades a database called sample40 to a 5.0 format, connecting as user dba with password sql:

dbupgrad -c "uid=dba;pwd=sql;dbf=c:\wsql40\sample40.db"

The DBUPGRAD command-line utility must be run by a user with DBA authority.

User ID for dbo user   SQL Anywhere contains a set of system views that mimic the system tables of Sybase SQL Server. By default, the owner of these views is the user ID dbo, which is the same as the owner of the SQL Server system tables. If you already have a user ID named dbo, or you wish to use that user ID for other purposes, this option allows you to provide an alternative user ID for the owner of the SQL Server-like system views. For the DBUPGRAD command-line utility, this is the -g command-line switch.

Close window on completion   Once the upgrade is completed, the message window is closed. For the DBUPGRAD command-line utility, this is the -k command line switch. This option is not available from other environments.

Operate quietly   Do not display messages on a window For the DBUPGRAD command-line utility, this is the -q command line switch. This option is not available from other environments.


The Validation utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Validation utility

With the Validation utility you can validate all 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 the chapter "Backup and Data Recovery") to give you confidence in the security of the data in your database.

You can access the Validation utility in the following ways:

♦	From Sybase Central, for interactive use under Windows 95 or NT.

♦	From the ISQL Database Tools window.

♦	From the ISQL DBTOOL statement.

♦	From the system command line, using the DBVALID command-line utility. This is useful for incorporating into batch or command files.

  For more information

For more information on validating tables, see "VALIDATE TABLE statement".

 Validating a database from Sybase Central

 Validating a database from the ISQL Database Tools window

 Using the Validation utility from the DBTOOL statement

 Using the DBVALID command line utility

 Validation utility options


Validating a database from Sybase Central
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Validation utility

Validating a database from Sybase Central

 To validate a running database:

1	Connect to the database.

2	Right-click the database and click Validate in the popup menu.

 To validate an individual table:

1	Connect to the database.

2	Locate the table you wish to validate.

3	Right-click the table and click Validate in the popup menu.

  For full information on validating a database from Sybase Central, see the Sybase Central online Help.


Validating a database from the ISQL Database Tools window
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Validation utility

Validating a database from the ISQL Database Tools window

 To use the Validation utility from the ISQL Database Tools window:

1	Select Database Tools from the Window menu.

2	Click Check Database Integrity on the Tools list.

3	Enter a user ID and password to use when connecting to the database.

4	For a running database, enter a database name and server name (if more than one is running). For a database file, enter the filename (with path) and optionally a start line to specify command line switches for the database engine or SQL Anywhere Client.

5	Click Check.

6	Enter a list of tables to validate, if you do not wish to validate the entire database, and click OK.


Using the Validation utility from the DBTOOL statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Validation utility

Using the Validation utility from the DBTOOL statement

The syntax for the Validation utility from the ISQL DBTOOL statement is as follows:

DBTOOL VALIDATE TABLES [ t1, t2, ..., tn ]

...   USING connection-string


Using the DBVALID command line utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Validation utility

Using the DBVALID command line utility

Syntax

dbvalid [switches] [table-name,...]

Windows 3.x syntax

dbvalidw [switches] [table-name,...]

Switch	Description
-c "keyword=value; ..."	Supply database connection parameters
-q	Quiet mode—do not print messages
  For more information about the command-line switches, see "Validation utility options".


Validation utility options
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Validation utility

Validation utility options

Connection parameters   For a description of the connection parameters, see "Database connection parameters". If the connection parameters are not specified, connection paremeters from the SQLCONNECT environment variable are used, if set. The user ID must have DBA authority.

For the DBVALID command-line utility, this is the -c command line switch. For example, the following validates the sample database, connecting as user dba with password sql:

dbvalid -c "uid=dba;pwd=sql;dbf=c:\sqlany50\sademo.db"

Operate quietly   Do not display messages on a window. For the DBVALID command-line utility, this is the -q command line switch. This option is not available from other environments.


The Write File utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Write File utility

The Write File utility is used to manage database write files. A write file is a file attached to a particular database. All changes are written into the write file, leaving the database file unchanged.

Using write files for development

Write files can be used effectively for testing when you do not wish to modify the production database. They can also be used in network and student environments where read-only access to a database is desired, or when you distribute on CD-ROM a database you wish users to be able to modify.

Compressed databases

If you are using a compressed database, then you must use a write file; compressed database files cannot be modified 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 engine or server command line.

 To access the Write File utility:

1	From Sybase Central, for interactive use under Windows 95 or NT.

2	From the ISQL Database Tools window.

3	From the ISQL DBTOOL statement.

4	From the system command line, using the DBWRITE command-line utility. 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 an engine when you run the Write File utility.

 Creating a write file from Sybase Central

 Creating a write file from the ISQL Database Tools window

 Creating a write file using the DBTOOL statement

 The DBWRITE command-line utility

 Write file utility options


Creating a write file from Sybase Central
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Write File utility

Creating a write file from Sybase Central

 To create a write file for a database:

1	Open the Database Utilities folder in the left panel.

2	Double-click Create Write File in the right panel. The Write File Wizard is displayed.

3	Follow the instructions in the Wizard.

  For full information on creating a write file from Sybase Central, see the Sybase Central online Help.


Creating a write file from the ISQL Database Tools window
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Write File utility

Creating a write file from the ISQL Database Tools window

 To use the Write File utility from the ISQL Database Tools window:

1	Select Database Tools from the Window menu.

2	Click Create Write File on the Tools list.

3	Enter the database filename (with path).

4	Click Create, and enter a filename to use for the write file and for the write file transaction log.

5	Click OK to create the write file.


Creating a write file using the DBTOOL statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Write File utility

Creating a write file using the DBTOOL statement

Syntax

The syntax for the Write File utility from the ISQL DBTOOL statement is as follows:

DBTOOL CREATE WRITEFILE filename FOR DATABASE filename

...   [ [ TRANSACTION ] LOG TO logname ] [ NOCONFIRM ]


The DBWRITE command-line utility
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Write File utility

The DBWRITE command-line utility

Syntax

dbwrite [switches] database-file [write-name]

Windows 3.x syntax

dbwritew [switches] database-file [write-name]

Switch	Description
-c	Create a new write file
-d database-file	Point a write file to a different database
-f database-file	Force write file to point at file
-m mirror-name	Set transaction log mirror name
-o file	Output messages to file
-q	Quiet mode—do not print messages
-s	Report write file status (default)
-t log-name	Set transaction log name
-y	Erase/replace old files without confirmation
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 engine using the original database file and make a modification to it. It can be made valid again by the command:

dbwrite -c db-name write-name

However, this deletes all changes recorded in the write file.

The log-name and mirror-name parameters are only used when creating a new write file. The write-name parameter is only used with the -c and -d parameters. Note that the db-name parameter must be specified before the write-name parameter.

  For more information about the command-line switches, see "Write file utility options".


Write file utility options
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The Write File utility

Write file utility options

Create a new write file    If an existing write already exists, any information in the old write file will be lost. If no write filename is specified on the command line, the write filename will default to the database name with the extension WRT. If no transaction log name is specified, the log filename will default to the database name with the extension WLG. For the DBWRITE command-line utility, this is the -c command-line switch.

Change the database file to which an existing write file points    If a database file is moved to another directory, or renamed, this option allow you to maintain the link between the write file and the database file. For the DBWRITE command-line utility, this is the -d command-line switch. The option is not available in other environments.

Force a write file to point to a file   For the DBWRITE command-line utility, this is the -f command-line switch. The option is not available in other environments. 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\\SADEMO.DB), dependencies on local mappings of the NetWare path can be avoided. Unlike the option to change the database file pointed to, no checking is done on the specified path.

Operate quietly   Do not display messages on a window. For the DBWRITE command-line utility, this is the -q command-line switch. This option is not available from other environments.

Report write file status only   This displays the name of the database that the write file points to. For the DBWRITE command-line utility, this is the -s command-line switch. The option is not available in other environments.

Operate without confirming actions   Without this option, you are prompted to confirm the replacement of an existing database file. For the DBWRITE command-line utility, this is the -y command-line switch.


The SQL Preprocessor
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 37. SQL Anywhere Components

The SQL Preprocessor

The SQL preprocessor processes a C or C++ program with embedded SQL before the compiler is run.

Syntax

sqlpp [switches] sql-filename [output-filename]

Switch	Description
-c	Favor code size
-d	Favor data size
-e level	Flag non-conforming SQL syntax as an error
-f	Put far keyword on generated static data
-h line-width	Limit maximum line length of output
-l userid, pswd	Logon identification
-n	Line numbers
-o operating-sys	Target operating system specification DOS, DOS32, DOS286, WINDOWS, WIN32 OS232, WINNT, NETWARE, QNX32(default is DOS, OS232, or WINNT)
-q	Quiet mode—do not print banner
-r	generate reentrant code
-s string-len	Maximum string constant length for compiler
-w level	Flag non-conforming SQL syntax as a warning
-z sequence	Specify collation sequence
 Description

The SQL preprocessor processes a C or C++ program with 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 sql-filename with an extension of C. If the sql-filename has a C. extension, then the output filename extension is CC by default.

Switches

-c   Generate code that will favor code size and execution speed over data space size. Statically initialized data structures will be used as much as possible. This is the default.

-d   Generate code that will reduce data space size. Data structures will be reused and initialized at execution time before use. This increases code size.

-e level   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

♦	w   allow all supported syntax

-f   Put the far keyword in front of preprocessor generated data. This may be required in conjunction with the Borland C++ compiler for the large memory model. By default, all static data is put in the same segment. Adding the far keyword will force static data into different segments. (By default, WATCOM C and Microsoft C place data objects bigger than a threshold size in their own segment.)

-h num   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.

-l userid, password   The named userid and password will be used for authorization of static SQL statements (see "Authorization").

-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 you are using supports the #line directive, this switch will make 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 will indirectly be used by the source level debugger so that you can debug while viewing the SQC source file.

-o operating-sys   Specify the target operating system. Note that this option must match the operating system you will be running the program in. 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:

DOS   MS-DOS or DR-DOS

DOS32   32-bit DOS extended program

DOS286   286 DOS extended program

WINDOWS   Microsoft Windows 3.x

WIN32   32-bit Microsoft Windows

OS232   32-bit OS/2

WINNT   Microsoft Windows NT

NETWARE   Novell NetWare

QNX   16-bit QNX

QNX32   32-bit QNX

The default is DOS for the DOS version of SQLPP, OS232 for the OS/2 version, WINNT for the Windows NT version and QNX for the QNX version.

-r   Generate reentrant code. This statement is only necessary when you are writing code that is reentrant (see "Multi-Threaded or Reentrant Code").

-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', 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 level   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

♦	w   allow all supported syntax

♦


Watcom-SQL Language Reference
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 38. Watcom-SQL Language Reference

About this chapter

This chapter presents detailed descriptions of the language elements and conventions of Watcom-SQL — one of two SQL dialects native to SQL Anywhere.

  For more information about Transact SQL, the other SQL dialect supported by SQL Anywhere, please see "Transact-SQL Procedure Language".

 Syntax conventions

 Watcom-SQL language elements

 Expressions

 Search conditions

 Comments in Watcom-SQL


Syntax conventions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 38. Watcom-SQL Language Reference

Syntax conventions

The following conventions are used in the SQL syntax descriptions:

♦	Keywords   All keywords are shown in uppercase. This is often the way SQL statements are typed. However, SQL Anywhere allows all keywords to be in mixed case. Thus SELECT is the same as Select which is the same as select.

♦	Placeholders   Items that the user must replace with appropriate identifiers or expressions are shown in lowercase.

♦	Options   Options are separated by vertical bars. Any one of the items is allowed.

♦	Continuation   Lines beginning with ... are a continuation of the statements from the previous line.

♦	Lists   Lists are shown with a list element followed by ",...". This means that one or more list elements are allowed and if more than one is specified, they must be separated by commas.

♦	Optional portions   Optional portions of a statement are enclosed by square brackets. For example, RELEASE SAVEPOINT [ savepoint-name ] indicates that the savepoint-name is optional. Alternative optional parts of a statement are sometimes listed within the brackets separated by vertical bars. For example, [ ASC | DESC ] indicates that ASC or DESC are optional.

♦	Alternatives   When one of the options must be chosen, the alternatives are enclosed in curly braces. For example [ QUOTES { ON | OFF } ] indicates that if the QUOTES option is chosen, one of ON or OFF must be provided. The braces should not be typed.


Watcom-SQL language elements
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 38. Watcom-SQL Language Reference

Watcom-SQL language elements

The following elements are found in the syntax of many SQL statements. Each of these elements is discussed in more detail later in this chapter.

column-name   An identifier representing the name of a column.

condition   An expression that evaluates to TRUE, FALSE, or UNKNOWN. See "Search conditions".

connection-name   An identifier or a string representing the name of an active connection.

owner   An identifier representing a user ID.

data-type   A storage data type as described in "SQL Anywhere Data Types".

expression   An expression, as described in "Expressions".

filename   A string containing a filename.

host-variable   A C language variable declared as a host variable preceded by a colon.

identifier   Any string of the characters A through Z, a through z, 0 through 9, underscore (_ ), at sign (@), number sign (#), or dollar sign ($). The first character must be a letter. Alternatively, any string of characters can be used as an identifier by enclosing it in quotation marks ("double quotes"). A quotation mark inside the identifier is represented by two quotation marks in a row. Identifiers are truncated to 128 characters. The following are all valid identifiers.

Surname

"Surname"

SomeBigName

some_big_name

"Client Number"

"With a quotation "" mark"

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

role-name   An identifier representing the role name of a foreign key.

search-condition   A condition that evaluates to TRUE, FALSE, or UNKNOWN. See "Search conditions".

string   Any sequence of characters enclosed in apostrophes ('single quotes'). An apostrophe is represented inside the string by two apostrophes in a row. A new line character is represented by a backslash followed by an n (\n). 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). A backslash character is represented by two backslashes in a row (\\). The following are valid strings:

'This is a string.'

'John''s database'

'\x00\x01\x02\x03'

savepoint-name   An identifier representing the name of a savepoint.

statement-label   An identifier representing the label of a loop or compound statement.

table-list   A list of table names which may include correlation names. See "FROM clause".

table-name   An identifier representing the name of a table.

userid   An identifier representing a user name.

variable   An identifier representing a variable name.


Expressions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 38. Watcom-SQL Language Reference

Expressions

Syntax

expression:

  constant

| [correlation-name .] column-name

| variable-name

| function-name ( expression, ... )

| - expression

| expression + expression

| expression - expression

| expression * expression

| expression / expression

| expression + expression

| expression || expression

| ( expression )

| ( subquery )

| CAST ( expression AS data-type )

| if-expression

constant:

  integer

| number

| 'string'

| special-constant

| host-variable

special-constant:

  CURRENT DATE

| CURRENT TIME

| CURRENT TIMESTAMP

| NULL

| SQLCODE

| SQLSTATE

| USER

if-expression:

IF condition THEN expression [ ELSE expression ] ENDIF

Usage

Anywhere.

Authorization

Must be connected to the database.

Side effects

None.

 Description

Expressions are formed from several different kinds of element, discussed in the following sections.

 Constants in expressions

 Column names in expressions

 Watcom-SQL variables

 Functions in expressions

 Subqueries in expressions

 Watcom-SQL Operators


Constants in expressions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 38. Watcom-SQL Language Reference

Expressions

Constants in expressions

Constants are numbers or strings. String constants are enclosed in apostrophes ('single quotes'). An apostrophe is represented inside the string by two apostrophes in a row.

There are several special constants:

♦	CURRENT DATE   The current year, month and day represented in the DATE data type.

♦	CURRENT TIME   The current hour, minute, second and fraction of a second represented in the TIME data type. Although the fraction of a second is stored to 6 decimal places, the current time is limited by the accuracy of the system clock.

Under DOS and Windows, the clock is only accurate to approximately 1/18th of a second rounded to two decimal places. Under QNX, the clock is accurate to the nearest microsecond.

♦	CURRENT TIMESTAMP   Combines CURRENT DATE and CURRENT TIME to form a TIMESTAMP value containing year, month, day, hour, minute, second and fraction of a second. Like CURRENT TIME, the accuracy of the fraction of a second is limited by the system clock.

In embedded SQL, a host variable can also be used in an expression wherever a constant is allowed.

♦	NULL   The NULL value (see "NULL value").

♦	SQLCODE   Current SQLCODE value (see the chapter "SQL Anywhere Database Error Messages").

♦	SQLSTATE   Current SQLSTATE value (see the chapter "SQL Anywhere Database Error Messages").

♦	CURRENT USER   A string containing the user ID of the current connection.

♦	CURRENT PUBLISHER   A string containing publisher user ID of the database for SQL Remote replications.

♦	LAST USER   For INSERTS, this constant has the same effect as CURRENT USER. For UPDATES, if a column with a default value of LAST USER is not explicitly altered, it is changed to the name of the current user. In this way, the LAST USER default indicates the user ID of the user who last modified the row.

When combined with the CURRENT 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..

In Embedded SQL, a host variable can also be used in an expression wherever a constant is allowed.


Column names in expressions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 38. Watcom-SQL Language Reference

Expressions

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"

  See "Watcom-SQL language elements" for a complete description of identifiers.


Watcom-SQL variables
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 38. Watcom-SQL Language Reference

Expressions

Watcom-SQL variables

SQL Anywhere supports three levels of variables:

♦	Local variables 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 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 are SQL Anywhere-supplied variables that have system-supplied values.

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.

Local variables can be passed as arguments to procedures, as long as the procedure is called from within the compound statement.

The following batch of SQL statements illustrates the use of local variables.

BEGIN

   DECLARE local_var INT ;

   SET local_var = 10 ;

   MESSAGE 'local_var = ', local_var ;

END

Running this batch from ISQL gives the message local_var = 10 on the engine window.

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 ;

   MESSAGE 'local_var = ', local_var ;

END;

MESSAGE 'local_var = ', local_var ;

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 ;

END

Running this batch from ISQL gives the message local_var = 10 on the engine window.

Connection-level variables

Connection-level variables are declared with the CREATE VARIABLE statement. The CREATE VARIABLE statement can be used anywhere except inside compound statements. Connection-level variables can be passed as parameters to procedures.

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. 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;

Running this batch from ISQL gives the message local_var = 10 on the engine window.

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

Global variables

Global variables are SQL Anywhere-supplied variables that have values set by the SQL Anywhere engine. For example, the global variable @@version has a value that is the current version number of the database engine.

Predefined global variables are distinguished from local and connection-level variables by having two @ signs preceding their names. For example, @@error, @@rowcount are global variables. Users cannot create global variables, and cannot update the value of global variables directly.

The special constants available in SQL Anywhere, such as CURRENT DATE, CURRENT TIME, USER, SQLSTATE and so on are similar to, but not identical to, global variables. The special constants can be used as defaults for columns; global variables cannot.

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 engine version number in the ver parameter.

CREATE PROCEDURE VersionProc ( OUT ver

            NUMERIC ( 5, 2 ) )

BEGIN

   SELECT @@version

   INTO ver;

END

In Embedded SQL, global variables can be selected into a host variable list.

The following table lists the global variables available in SQL Anywhere

Variable name	Meaning
@@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.
@@identity	Last value inserted into an IDENTITY column by an insert or select into statement. @@identity 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.
@@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. @@rowcount is set to zero by any statement which does not return rows, such as an if statement. 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 current database server.
@@sqlstatus	Contains status information resulting from the last fetch statement.
@@version	Version of the current version of SQL Anywhere.


Functions in expressions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 38. Watcom-SQL Language Reference

Expressions

Functions in expressions

See "Watcom-SQL Functions" for a description of the functions available in SQL Anywhere.


Subqueries in expressions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 38. Watcom-SQL Language Reference

Expressions

Subqueries in expressions

A subquery is a SELECT statement enclosed in parentheses. The SELECT statement must contain one and only one select list item. Usually, the subquery is allowed to return only one row. See "Search conditions" for other uses of subqueries. 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.


Watcom-SQL Operators
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 38. Watcom-SQL Language Reference

Expressions

Watcom-SQL Operators

This section describes the arithmetic and string operators available in SQL Anywhere. 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.

expression + expression   Addition. If either expression is the NULL value, the result is the NULL value.

expression - expression   Subtraction. If either expression is the NULL value, the result is the NULL value.

- expression   Negation. If the expression is the NULL value, the result is the NULL value.

expression * expression   Multiplication. If either expression is the NULL value, the result is the NULL value.

expression / expression   Division. If either expression is the NULL value or if the second expression is 0, the result is the NULL value.

expression || expression   String concatenation (two vertical bars). If either string is the NULL value, 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.

( expression )   Parentheses.

IF condition THEN expression1 [ELSE expression2] ENDIF   Evaluates to the value of expression1 if the specified search condition is TRUE, the value of expression2 if condition is FALSE, and the NULL value if condition is UNKNOWN. (For more information about TRUE, FALSE and UNKNOWN conditions, see "NULL value", and "Search conditions".)


Search conditions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 38. Watcom-SQL Language Reference

Search conditions

Purpose

To specify a search condition for a WHERE clause, a HAVING clause, a CHECK clause, a JOIN clause or an IF expression.

Syntax

search condition:

  expression compare expression

| expression compare ANY ( subquery )

| expression compare ALL ( subquery )

| expression IS [ NOT ] NULL

| expression [ NOT ] LIKE expression [ESCAPE expression]

| expression [ NOT  BETWEEN expression AND expression

| expression [ NOT ] IN ( expression )

| expression [ NOT ] IN ( subquery )

| expression [ NOT ] IN (value-expr1 , value-expr2 [, value-expr3 ] ... )

| EXISTS ( subquery )

| NOT condition

| condition AND condition

| condition OR condition

| ( condition )

| ( condition , estimate )

| condition IS [ NOT ] TRUE

| condition IS [ NOT ] FALSE

| condition IS [ NOT ] UNKNOWN

compare:

one of = > < >= <= <> != ~= !< !>

Usage

Anywhere.

Authorization

Must be connected to the database.

Side effects

None.

 Description

Conditions are used as 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.

SQL conditions do not follow boolean logic, where conditions are either true or false. 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 showing 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 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.

 Subqueries in search conditions

 Comparison conditions

 BETWEEN conditions

 LIKE conditions

 IN conditions

 ALL or ANY conditions

 EXISTS conditions

 IS NULL conditions

 Conditions with logical operators

 NOT conditions

 Truth value conditions

 Three-valued logic


Subqueries in search conditions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 38. Watcom-SQL Language Reference

Search conditions

Subqueries in search conditions

Subqueries that return exactly one column and either zero or one row can be used in any SQL statement anywhere that 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 conditions") 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 returning any number of columns and rows can be used in EXISTS conditions. These conditions are discussed in the following sections.


Comparison conditions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 38. Watcom-SQL Language Reference

Search conditions

Comparison conditions

The syntax for comparison conditions is as follows:

... expression compare expression

where compare is a comparison operator. The following comparison operators are available in SQL Anywhere:

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
Comparisons are case insensitive—All string comparisons are case insensitive unless the database was created as case sensitive.


BETWEEN conditions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 38. Watcom-SQL Language Reference

Search conditions

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, leaving UNKNOWN unchanged.

The BETWEEN conditions is equivalent to a combination of two inequalities:

expr >= start-expr AND expr <= end-expr


LIKE conditions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 38. Watcom-SQL Language Reference

Search conditions

LIKE conditions

The syntax for LIKE conditions is as follows:

... expression [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, leaving UNKNOWN unchanged.

The pattern may contain any number of wild cards. The wild cards are:

Wild card	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.

Using ranges and sets in patterns

Ranges and sets of characters can be given in LIKE search conditions using square brackets.

Searching for one of a set of characters

A set of characters to look for is specified by listing the characters inside the 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, 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 the chapter "Database Collations".

The lower end of the range must precede the higher end of the range. For example, any LIKE condition containing the expression [z-a] returns no rows, as no character matches the [z-a] range.

Unless the database was created as a case-insensitive database, 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.

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 wild card 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 wild cards 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.


IN conditions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 38. Watcom-SQL Language Reference

Search conditions

IN conditions

The syntax for IN conditions is as follows:

...expression [ NOT ] IN ( subquery )

|   expression [ NOT ] IN ( expression )

|   expression [ NOT ] IN (value-expr1 , value-expr2 [, value-expr3 ] ... )

Without the NOT keyword, the IN conditions is TRUE if expression equals any of the listed values, UNKNOWN if expression is the NULL value, and FALSE otherwise. The NOT keyword reverses the meaning of the condition, leaving UNKNOWN unchanged.


ALL or ANY conditions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 38. Watcom-SQL Language Reference

Search conditions

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 is 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.


EXISTS conditions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 38. Watcom-SQL Language Reference

Search conditions

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.


IS NULL conditions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 38. Watcom-SQL Language Reference

Search conditions

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 as FALSE otherwise. The NOT keyword reverses the meaning of the condition.


Conditions with logical operators
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 38. Watcom-SQL Language Reference

Search conditions

Conditions with 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 result of a comparison is UNKNOWN if either value being compared is the NULL value. Rows satisfy a search condition if and only if the result of the condition is TRUE.


NOT conditions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 38. Watcom-SQL Language Reference

Search conditions

NOT conditions

The syntax for NOT conditions is as follows:

... NOT condition1

The NOT condition is TRUE if condition1 is FALSE, FALSE if condition1 is TRUE and UNKNOWN if condition1 is UNKNOWN.


Truth value conditions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 38. Watcom-SQL Language Reference

Search conditions

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, leaving UNKNOWN unchanged.


Three-valued logic
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 38. Watcom-SQL Language Reference

Search conditions

Three-valued logic

The following tables show how the AND, OR, NOT, and IS logical operators of SQL work in three-valued logic.

AND	TRUE	FALSE	UNKNOWN
TRUE	TRUE	FALSE	UNKNOWN
FALSE	FALSE	FALSE	FALSE
UNKNOWN	UNKNOWN	FALSE	UNKNOWN
OR	TRUE	FALSE	UNKNOWN
TRUE	TRUE	TRUE	TRUE
FALSE	TRUE	FALSE	UNKNOWN
UNKNOWN	TRUE	UNKNOWN	UNKNOWN
NOT	TRUE	FALSE	UNKNOWN
	FALSE	TRUE	UNKNOWN
IS	TRUE	FALSE	UNKNOWN
TRUE	TRUE	FALSE	FALSE
FALSE	FALSE	TRUE	FALSE
UNKNOWN	FALSE	FALSE	TRUE


Comments in Watcom-SQL
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 38. Watcom-SQL Language Reference

Comments in Watcom-SQL

Comments are used to attach explanatory text to SQL statements or statement blocks. Comments are not executed by the database engine.

Several comment indicators are available in SQL Anywhere.

-- (Double hyphen.)   Any remaining characters on the line are ignored by the database engine. This is the SQL/92 comment indicator.

% (Percent sign.)   The percent sign has the same meaning as the double hyphen.

// (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.

Transact-SQL compatibility—The double-hyphen and the slash-asterisk comment styles are compatible with Transact-SQL.

The following examples illustrate the use of 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

/*

   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


SQL Anywhere Data Types
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 39. SQL Anywhere Data Types

About this chapter

This chapter describes the data types supported by SQL Anywhere.

  For more information

♦	The different kinds of data type are discussed in the following sections.

♦	Data type conversions are described in the section "Data type conversions".

♦	Some of the data types listed have Transact-SQL equivalents. These equivalents are not listed here. For a description of Transact-SQL data types supported by SQL Anywhere, see the chapter "Using Transact-SQL with SQL Anywhere".

 Character data types

 Numeric data types

 Date and time data types

 Binary data types

 User-defined data types

 Data type conversions

 Year 2000 compliance


Character data types
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 39. SQL Anywhere Data Types

Character data types

Purpose

For storing strings of letters, numbers and symbols.

Syntax

Character data types:

  CHAR [ ( max-length ) ]

| CHARACTER [ ( max-length ) ]

| CHARACTER VARYING [ ( max-length ) ]

| LONG VARCHAR

| VARCHAR [ ( max-length ) ]

Description

CHAR [(max-length)]   Character data of maximum length max-length. If max-length is omitted, the default is 1. The maximum size allowed is 32,767.

  See the notes below on character data representation in the database, and on storage of long strings.

CHARACTER [(max-length)]   Same as CHAR[(max-length)].

CHARACTER VARYING[(max-length)]   Same as CHAR[(max-length)].

LONG VARCHAR   Arbitrary length character data. The maximum size is limited by the maximum size of the database file (currently 2 gigabytes).

VARCHAR [(max-length)]   Same as CHAR[(max-length)].

Notes

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.

All 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 different machine using 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 multiuser server, but running with different code pages. Data inserted or updated by one client may appear incorrect to another.

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.

Long strings

SQL Anywhere treats CHAR, VARCHAR, and LONG VARCHAR columns all as the same type. Values up to 254 characters are stored as short strings, which are stored with a preceding length byte. Any values that are longer than 255 bytes are considered long strings. Characters after the 255th are stored separate from the row containing the long string value.

There are several functions (see "Watcom-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 will work with the full length of long strings.


Numeric data types
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 39. SQL Anywhere Data Types

Numeric data types

Purpose

For storing numerical data.

Syntax

Numeric data types

  DECIMAL [ ( precision [ , scale ] ) ]

| DOUBLE

| FLOAT [ ( precision ) ]

| INT

| INTEGER

| NUMERIC [ ( precision [ , scale ] ) ]

| REAL

| SMALLINT

| TINYINT

Description

DECIMAL [(precision[,scale])]   A decimal number with precision total digits and with scale of the digits after the decimal point. The defaults are scale = 6 and precision = 30.

These defaults can be changed with the SET statement (see "SET OPTION statement").

The storage required for a decimal number can be computed as:

2 + int( (before+1) / 2 ) + int( (after+1)/2 )

where int takes the integer portion of its argument, and before and after are the number of significant digits before and after the decimal point. Note that the storage is based on the value being stored, not on the maximum precision and scale allowed in the column.

DOUBLE   A double precision floating-point number stored in 8 bytes. The range of values is 2.22507385850720160e-308 to 1.79769313486231560e+308. Values held as DOUBLE are accurate to 15 significant digits, but may be subject to round-off error beyond the fifteenth digit.

FLOAT [ ( precision ) ]    If precision is not supplied, the FLOAT data type is the same as the REAL data type. If precision supplied, then the FLOAT data type is the same as the REAL or DOUBLE data type, depending on the value of the precision.  The cutoff between REAL and DOUBLE is platform dependent.

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.

INT   Signed integer of maximum value 2,147,483,647 requiring 4 bytes of storage.

INTEGER   Same as INT.

NUMERIC [(precision[,scale])]   Same as DECIMAL.

REAL   A single precision floating-point number stored in 4 bytes. The range of values is 1.175494351e-38 to 3.402823466e+38. Values held as REAL are accurate to 6 significant digits, but may be subject to round-off error beyond the sixth digit.

SMALLINT   Signed integer of maximum value 32,767 requiring 2 bytes of storage.

TINYINT   Signed integer of maximum value 255 requiring 2 bytes or 4 bytes of storage.

Notes

♦	The INTEGER, NUMERIC and DECIMAL 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. Columns holding exact numeric data are accurate after arithmetic operations to the least significant digit specified.

♦	In SQL Anywhere TINYINT columns should not be fetched into Embedded SQL 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.

♦	Before release 5.5, hexadecimal constants greater 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.


Date and time data types
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 39. SQL Anywhere Data Types

Date and time data types

Purpose

For storing dates and times.

Syntax

Date and time data types

  DATE

| TIME

| TIMESTAMP

Description

DATE   A calendar date, such as a year, month and day. The year can be from the year 0001 to 9999. For historical reasons, a DATE column can also contain an hour and minute, but the TIMESTAMP data type is now recommended for anything with hours and minutes. A DATE value requires 4 bytes of storage.

TIME   time of day, containing hour, minute, second and fraction of a second. 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.)

TIMESTAMP   point in time, containing year, month, day, hour, minute, second and fraction of a second. 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, 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.

 Sending dates and times to the database

 Unambiguous dates and times

 Retrieving dates and times from the database

 Date and time comparisons


Sending dates and times to the database
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 39. SQL Anywhere Data Types

Date and time data types

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


Unambiguous dates and times
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 39. SQL Anywhere Data Types

Date and time data types

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.SSSSSS

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. SQL Anywhere can interpret a wide range of strings as formats. 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 SQL Anywhere ODBC driver sets the DATE_ORDER option to 'YMD' whenever a connection is made. The value can still be changed using the SET OPTION statement.

The database option DATE_ORDER determines whether the string 10/11/12 is interpreted by the database as Oct 11 1912, Nov 12 1910, or Nov 10 1912. The year, month, and day of a date string should be separated by some character (for example /, -, or space) and appear in the order specified by the DATE_ORDER option. The year can be supplied as either 2 or 4 digits, with 2 digit years defaulting to the 20th century. 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.

With an appropriate setting of DATE_ORDER, the following strings are all valid dates:

92-05-23 21:35

92/5/23

1992/05/23

May 23 1992

23-May-1992

Tuesday May 23, 1992 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 1992' will be the date '1992-05-01 00:00' )

hour, minute, second, fraction   0


Retrieving dates and times from the database
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 39. SQL Anywhere Data Types

Date and time data types

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 dealing 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.


Date and time comparisons
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 39. SQL Anywhere Data Types

Date and time data types

Date and time comparisons

The DATE data type also contains a time. 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 always involve the times as well. A database date value of '1992-05-23 10:00' will not be equal to the constant '1992-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') = '1992/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.


Binary data types
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 39. SQL Anywhere Data Types

Binary data types

Purpose

For storing binary data, including images and other information that is not interpreted by the database.

Syntax

Binary data types:

 BINARY [ ( max-length ) ]

| LONG BINARY

Description

BINARY [(max-length)]   Binary data of maximum length size (in bytes). If size is omitted, the default is 1. The maximum size allowed is 32,767. The BINARY data type is identical to the CHAR data type except when used in comparisons. BINARY values will be compared exactly while CHAR values are compared without respect to upper/lowercase (depending on the case-sensitivity of the database) or accented characters.

LONG BINARY   Arbitrary length binary data. The maximum size is limited by the maximum size of the database file (currently 2 gigabytes).


User-defined data types
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 39. SQL Anywhere Data Types

User-defined data types

Purpose

User-defined data types are aliases for built-in data types, including precision and scale values where applicable, and optionally including DEFAULT values and CHECK conditions.

User-defined data types, also called domains, 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. This encourages consistency throughout the database.

Simple user-defined data types

User-defined data types are created using the CREATE DATATYPE statement For full description of the syntax, see "CREATE DATATYPE statement".

The following statement creates a data type named street_address, which is a 35-character string.

CREATE DATATYPE street_address CHAR( 35 )

CREATE DOMAIN can be used as an alternative to CREATE DATATYPE, and is recommended, as 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 DATATYPE statement is the owner of that data type. Any user can use the data type, and unlike 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

)

User-defined data types can be dropped by their owner or by the DBA using the DROP DATATYPE statement:

DROP DATATYPE street_address

This statement can be carried out only if the data type is not used in any table in the database.

Constraints and defaults with user-defined data types

Many of the attributes associated with columns, such as allowing NULL values, having a DEFAULT value, and so on, can be built into a user-defined data type. 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 DATATYPE 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 autoincremented 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.


Data type conversions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 39. SQL Anywhere Data Types

Data type conversions

Type conversions 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 expecting a numeric argument, the string is converted to a number before use.

If a number is used in a string expression or as a string function argument, then the number is converted to a string before use.

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 -- SQL Anywhere tries to convert the string to a number

'a' > 0 -- SQL Anywhere tries to convert 'a' to a number

The CAST or CONVERT functions can be used 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  "Watcom-SQL Functions").

DATE( value )      Converts the expression into a date, and removes any hours, minutes or seconds. Conversion errors may be reported.

STRING( value )   similar to CAST( value AS CHAR ), except that string( NULL ) is the empty string (''), while CAST( NULL AS CHAR ) is the NULL value.

VALUE+0.0   Equivalent to CAST( value AS DECIMAL ).


Year 2000 compliance
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 39. SQL Anywhere Data Types

Year 2000 compliance

The problem of handling dates, in particular year values beyond the year 2000, is a significant issue for the computer industry.

This section examines the year 2000 compliance of SQL Anywhere. It illustrates how date values are handled internally by SQL Anywhere, and how SQL Anywhere handles ambiguous date information, such as the conversion of a two digit year string value.

Users of Sybase SQL 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 SQL Anywhere's year 2000 compliance:

♦	SQL 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 SQL Anywhere's internal storage of dates explicitly includes the century portion of a year value.

♦	SQL Anywhere's operation is unaffected by any return value, including the current date.

♦	Date values can always be outputted 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. Links to relevant sections are provided.

 How dates are stored

 Sending and retrieving date values

 Leap years

 Ambiguous string to date conversions

 Date to string conversions


How dates are stored
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 39. SQL Anywhere Data Types

Year 2000 compliance

How dates are stored

Dates containing year values are used internally and stored in SQL 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 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 SQL Anywhere date and time data types see "Date and time data types".


Sending and retrieving date values
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 39. SQL Anywhere Data Types

Year 2000 compliance

Sending and retrieving date values

Date values are stored within SQL Anywhere as either a DATE or TIMESTAMP data type, but they are passed to and retrieved from SQL Anywhere using either of three methods:

♦	As a string, using any SQL 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).

Date formats other than yyyy-mm-dd can be used by setting the DATE_FORMAT database option (see "SET OPTION statement").

  For more information on unambiguous date formats, see "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 interface data types".


Leap years
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 39. SQL Anywhere Data Types

Year 2000 compliance

Leap years

The year 2000 is also a leap year, with an additional day in the month of February. SQL 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 if it is divisible by 400.

SQL Anywhere handles all leap years correctly. For example:

The following SQL statement results in a return value of "Tuesday":

SELECT DAYNAME('2000-02-29');

SQL Anywhere accepts Feb 29, 2000 — a leap year — as a date and using this date determines the day of the week on which that date occurs.

However, the following statement is rejected by SQL Anywhere:

SELECT DAYNAME('2001-02-29');

This statement results in an error (cannot convert '2001-02-29' to a date) because Feb 29 does not exist in the year 2001, which it does not.


Ambiguous string to date conversions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 39. SQL Anywhere Data Types

Year 2000 compliance

Ambiguous string to date conversions

SQL 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, SQL Anywhere's 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 1900 date values and 2000 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 0 is assumed, thus adding 1900 to two digit year strings and placing them in the 20th century.

This NEAREST_CENTURY option was introduced in SQL Anywhere Release 5.5.

Ambiguous date conversion example

The following statement creates a table that can be used to illustrate the conversion of ambiguous date information in SQL 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. SQL 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 0, thus SQL Anywhere converts the string into the date 1900-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 = 25;

When NEAREST_CENTURY option is set to 25, 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 2000-01-01. Use the following statement to verify the results.

SELECT * FROM T1;


Date to string conversions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 39. SQL Anywhere Data Types

Year 2000 compliance

Date to string conversions

SQL Anywhere provides several functions for converting SQL 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 Jan 1, 2000 into a string representing the date Jan 1, 1900 even though no database error occurs.

SELECT DATEFORMAT (

         DATEFORMAT('2000-01-01', 'Mmm dd/yy' ),

         'yyyy-Mmm-dd' )

         AS Wrong_year;

Although the unambiguous date string 2000-01-01 is automatically and correctly converted by SQL Anywhere into a date value, 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 in the 20th century.

  For more information about ambiguous string conversions, see "Ambiguous string to date conversions".

  For more information on date and time functions, see "Date and time functions".


Watcom-SQL Functions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 40. Watcom-SQL Functions

About this chapter

This chapter describes the built-in functions supported by SQL Anywhere. Functions are used to return information from the database. They are allowed anywhere an expression is allowed.

NULL value—Unless otherwise stated, any function that receives the NULL value as a parameter returns a NULL value.

  For more information

Some of the functions listed have Transact-SQL equivalents that are not listed here. For a description of Transact-SQL functions supported by SQL Anywhere, see the chapter "Using Transact-SQL with SQL Anywhere".

 Aggregate functions

 Numeric functions

 String functions

 Date and time functions

 Data type conversion functions

 System functions

 Miscellaneous functions


Aggregate functions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 40. Watcom-SQL Functions

Aggregate functions

Purpose

Aggregate functions summarize data over a group of rows from the database.

Syntax

Aggregate function:

 AVG ( aggregate-parm )

| COUNT ( * )

| COUNT ( aggregate-parm )

| LIST ( aggregate-parm )

| MAX ( aggregate-parm )

| MIN ( aggregate-parm )

| SUM ( aggregate-parm )

aggregate-parm:

  DISTINCT column-name

| expression

 Description

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 only allowed in the select list and in the HAVING and ORDER BY clauses of a SELECT statement.

AVG( numeric-expr )   Computes the average of numeric-expr for each group of rows. This average does not include rows where the expression is the NULL value. Returns the NULL value for a group containing no rows.

AVG( DISTINCT column-name )   Computes the average of the unique values in column-name. This is of limited usefulness, but is included for completeness.

COUNT( * )   Returns the number of rows in each group.

COUNT( expression )   Returns the number of rows in each group where the expression is not the NULL value.

COUNT( DISTINCT column-name )   Returns the number of different values in the column with name column-name. Rows where the value is the NULL value are not included in the count.

LIST( string-expr )   Returns a string containing a comma-separated list composed of all the values for string-expr in each group of rows. Rows where string-expr is the NULL value are not added to the list.

LIST( DISTINCT column-name)   Returns a string containing a comma-separated list composed of all the different values for string-expr in each group of rows. Rows where string-expr is the NULL value are not added to the list.

MAX( expression )   Returns the maximum expression value found in each group of rows. Rows where expression is the NULL value are ignored. Returns the NULL value for a group containing no rows.

MAX( DISTINCT column-name )   Returns the same as MAX(expression), and is included for completeness.

MIN( expression )   Returns the minimum expression value found in each group of rows. Rows where expression is the NULL value are ignored. Returns the NULL value for a group containing no rows.

MIN( DISTINCT column-name )   Returns the same as MIN( expression ), and is included for completeness.

SUM( expression )   Returns the total of expression for each group of rows. Rows where the expression is the NULL value are not included. Returns NULL for a group containing no rows.

SUM( DISTINCT column-name )   Computes the sum of the unique values for numeric-expr for each group of rows. This is of limited usefulness, but is included for completeness.


Numeric functions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 40. Watcom-SQL Functions

Numeric functions

Purpose

Numeric functions perform mathematical operations on numerical data types or return numeric information.

Syntax

Numeric function:

  ABS ( numeric-expr )

| ACOS ( numeric-expr )

| ASIN ( numeric-expr )

| ATAN ( numeric-expr )

| ATAN2 ( numeric-expr, numeric-expr )

| CEILING ( numeric-expr )

| COS ( numeric-expr )

| COT ( numeric-expr )

| DEGREES (numeric-expr )

| EXP ( numeric-expr )

| FLOOR ( numeric-expr )

| LOG ( numeric-expr )

| LOG10 ( numeric-expr )

| MOD ( dividend, divisor )

| PI ( * )

| POWER ( numeric-expr, numeric-expr )

| RADIANS ( numeric-expr )

| RAND ( [integer-expr] )

| REMAINDER ( numeric-expr, numeric-expr )

| ROUND ( numeric-expr, integer-expr )

| SIGN ( numeric-expr )

| SIN ( numeric-expr )

| SQRT ( numeric-expr )

| TAN ( numeric-expr )

| "TRUNCATE" ( numeric-expr, integer-expr )

 Description

ABS( numeric-expr )   Returns the absolute value of numeric-expr.

ACOS( numeric-expr )   Returns the arc-cosine of numeric-expr in radians.

ASIN( numeric-expr )   Returns the arc-sine of numeric-expr in radians.

ATAN( numeric-expr )   Returns the arc-tangent of numeric-expr in radians.

ATAN2( numeric-expr1, numeric-expr2 )   Returns the arc-tangent of numeric-expr1/numeric-expr2 in radians.

CEILING( numeric-expr )   Returns the ceiling (smallest integer not less than) of numeric-expr.

COS( numeric-expr )   Returns the cosine of numeric-expr, expressed in radians.

COT( numeric-expr )   Returns the cotangent of numeric-expr, expressed in radians.

DEGREES( numeric-expr )   Converts numeric-expr, from radians to degrees.

EXP( numeric-expr )   Returns the exponential function of numeric-expr.

FLOOR( numeric-expr )   Returns the floor (largest integer not greater than) of numeric-expr.

LOG( numeric-expr )   Returns the logarithm of numeric-expr.

LOG10( numeric-expr )   Returns the logarithm base 10 of numeric-expr.

MOD( dividend, divisor )   Returns the remainder when dividend is divided by divisor. Division involving a negative dividend will give a negative or zero result. The sign of the divisor has no effect.

PI( * )   Returns the numeric value PI.

POWER ( numeric-expr1, numeric-expr2 )   Raises numeric-expr1 to the power numeric-expr2.

RADIANS ( numeric-expr )   Converts numeric-expr, from degrees to radians.

RAND ( [ integer-expr ] )   Returns a random number in the interval 0 to 1, with integer-expr as an optional seed.

REMAINDER( dividend, divisor )   Same as the MOD function.

ROUND ( numeric-expr, integer-expr )   Rounds numeric-expr to integer-expr places after the decimal point. A positive integer determines the number of significant digits to the right of the decimal point; a negative integer, the number of significant digits to the left of the decimal point.

SIGN( numeric-expr )   Returns the sign of numeric-expr.

SIN( numeric-expr )   Returns the sine of numeric-expr, expressed in radians.

SQRT( numeric-expr )   Returns the square root of numeric-expr.

TAN( numeric-expr )   Returns the tangent of numeric-expr, expressed in radians.

"TRUNCATE" ( numeric-expr, integer-expr )   Truncates numeric-expr at integer-expr places after the decimal point. A positive integer determines the number of significant digits to the right of the decimal point; a negative integer, the number of significant digits to the left of the decimal point.

The double quotes are required because of a keyword conflict with the TRUNCATE TABLE statement.


String functions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 40. Watcom-SQL Functions

String functions

Purpose

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.

Syntax

String function:

  ASCII ( string-expr )

| BYTE_LENGTH ( string-expr )

| BYTE_SUBSTR ( string-expr, integer-expr [, integer-expr ] )

| CHAR ( string-expr )

| DIFFERENCE (string-expr, string-expr )

| INSERTSTR ( numeric-expr, string-expr, string-expr )

| LCASE ( string-expr )

| LEFT ( string-expr, numeric-expr )

| LENGTH ( string-expr )

| LOCATE ( string-expr, string-expr [, numeric-expr ] )

| LTRIM ( string-expr )

| PATINDEX ( '%pattern%', string_expr )

| REPEAT ( string-expr, numeric-expr )

| RIGHT ( string-expr, numeric-expr )

| RTRIM ( string-expr )

| SIMILAR ( string-expr, string-expr )

| SOUNDEX ( string-expr )

| SPACE ( integer-expr )

| STRING ( string-expr [, ...] )

| SUBSTR ( string-expr, integer-expr [, integer-expr] )

| TRIM ( string-expr )

| UCASE ( string-expr )

 Description

ASCII( string-expr )   Returns the integer ASCII value of the first byte in string-expr, or 0 for the empty string.

BYTE_LENGTH( string-expr )   Returns the number of bytes in the string string-expr.

BYTE_SUBSTR( string-expr, start [, length] )   Returns the substring of string-expr starting at the given start position (origin 1), in bytes. If the length is specified, the substring is restricted to that number of bytes. Both start and length can be negative. A negative starting position specifies a number of bytes from the end of the string instead of the beginning. A positive length specifies that the substring ends length bytes to the right of the starting position, while a negative length specifies that the substring ends length bytes to the left of the starting position. Using appropriate combinations of negative and positive numbers, you can get a substring from either the beginning or end of the string.

CHAR( numeric-expr )   Returns the character with the ASCII value  numeric-expr. The character  in the current character set corresponding to  the supplied numeric expression modulo 256 is  returned. If you are using multi-byte character  sets, CHAR may not return a valid character.

DIFFERENCE( string-expr1, string-expr2 )   Returns the difference in the soundex values of  string-expr1 and string-expr2.

INSERTSTR( numeric-expr, string-expr1, string-expr2)   Inserts string-expr2 in string-expr1 at character position numeric-expr.

LCASE( string-expr )   Converts all characters in string-expr to lower case.

LEFT( string-expr, numeric-expr )   Returns the leftmost numeric-expr characters of string-expr.

LENGTH( string-expr )   Returns the number of characters in the string string-expr. If string-expr is of binary data type, the LENGTH function behaves as BYTE_LENGTH.

LOCATE( string-expr1, string-expr2 [, numeric-expr ] )   Returns the character offset (base 1) into the string string-expr1  of the first occurrence of the string string-expr2.  If numeric-expr is specified, the search will start 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.

LTRIM( string-expr )   Returns string-expr with leading blanks removed.

PATINDEX( '%pattern%', string-expr )   Returns an integer representing the starting position in characters of the first occurrence of pattern in the specified string expression, or a zero if pattern is not found. If the leading percent wild card is omitted, PATINDEX returns one (1) if pattern occurs at the beginning of the string, and zero if not. If the trailing percent wild card is omitted, PATINDEX returns one (1) if pattern occurs at the end of the string, and zero if not. If pattern starts with a percent wild card, then the two leading percent wild cards are treated as one.

REPEAT( string-expr, integer-expr )   Returns a string comprised of integer-expr instances of string-expr, concatenated together.

RIGHT( string-expr, numeric-expr )   Returns the rightmost numeric-expr characters  of string-expr.

RTRIM( string-expr   Returns string-expr with trailing blanks removed.

SIMILAR( string-expr1, string-expr2 )   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 (100 percent match if the two strings are identical).

This function can be very useful for correcting 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.

SOUNDEX( string-expr )   Returns a number representing the sound of the string-expr. Although it is not perfect, soundex will normally return the same number for words which sound similar and start with the same letter. For example:

soundex( 'Smith') = soundex( 'Smythe' )

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.

STRING( string1, [ string2, .., string99 ] )   Concatenates the strings into one large string. NULL values are treated as empty strings (''). Any numeric or date parameters are automatically converted to strings before concatenation. The STRING function can also be used to force any single expression to be a string by supplying that expression as the only parameter.

SUBSTR( string-expr, start [, length] )   Returns the substring of string-expr starting at the given start position (origin 1). If the length is specified, the substring is restricted to that length. Both start and length can be negative. A negative starting position specifies a number of characters from the end of the string instead of the beginning. A positive length specifies that the substring ends length characters to the right of the starting position, while a negative length specifies that the substring ends length characters to the left of the starting position. Using appropriate combinations of negative and positive numbers, you can easily get a substring from either the beginning or end of the string. If string-expr is of binary data type, the SUBSTR function behaves as BYTE_SUBSTR.

TRIM( string-expr )   Returns string-expr with both leading and trailing blanks removed.

UCASE( string-expr )   Converts all characters in string-expr to uppercase.


Date and time functions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 40. Watcom-SQL Functions

Date and time functions

Purpose

Date and time functions perform conversion, extraction or manipulation operations on date and time data types and can return date and time information.

Syntax

Date and time function:

| DATE ( expression )

| DATEFORMAT ( datetime-expr, string-expr )

| DATENAME ( datepart, date-expr )

| DATETIME ( expression )

| DAY ( date-expr )

| DAYNAME( date-expr )

| DAYS ( date-expr )

| DAYS ( date-expr, date-expr )

| DAYS ( date-expr, integer-expr )

| DOW ( date-expr )

| HOUR ( datetime-expr )

| HOURS ( datetime-expr )

| HOURS ( datetime-expr, datetime-expr )

| HOURS ( datetime-expr, integer-expr )

| MINUTE ( datetime-expr )

| MINUTES ( datetime-expr )

| MINUTES ( datetime-expr, datetime-expr )

| MINUTES ( datetime-expr, integer-expr )

| MONTH ( date-expr )

| MONTHNAME ( date-expr )

| MONTHS ( date-expr )

| MONTHS ( date-expr, date-expr )

| MONTHS ( date-expr, integer-expr )

| NOW ( * )

| QUARTER( date-expr )

| SECOND ( expression )

| SECONDS ( datetime-expr )

| SECONDS ( datetime-expr, datetime-expr )

| SECONDS ( datetime-expr, integer-expr )

| TODAY ( * )

| WEEKS ( date-expr )

| WEEKS ( date-expr, date-expr )

| WEEKS ( date-expr, integer-expr )

| YEAR ( date-expr )

| YEARS ( date-expr )

| YEARS ( date-expr, date-expr )

| YEARS ( date-expr, integer-expr )

| YMD ( integer-expr, integer-expr, integer-expr )

 Description

The date and time functions allow manipulation of time units. Most time units (such as MONTH) have four functions for time manipulation, although only two names are used (such as MONTH and MONTHS).

SQL Anywhere also supports several Transact-SQL date and time functions, allowing an alternative way of accessing and manipulating date and time functions. For information about the Transact-SQL date and time functions, see "Compatibility of date and time functions".

Arguments to date functions should be converted to dates before being used, so that

days ( '1995-11-17', 2 )

is not correct, but

days ( date( '1995-11-17' ), 2 )

is correct.

DATE( expression )   Converts the expression into a date, and removes any hours, minutes or seconds. Conversion errors may be reported.

DATEFORMAT( date-expr, string-expr )   Returns a string representing the date date-expr in the format specified by string-expr. Any allowable date format can be used for string-expr.

For example,

DATEFORMAT('1989-01-01', 'Mmm Dd, yyyy')

is

'Jan 1, 1989'

Year 2000 compliance—It is possible in using 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 "Date to string conversions".

  For more information, see the DATE_FORMAT option in "SET OPTION statement".

DATENAME ( datepart, date )   Returns the name of the specified part (such as the month "June") of a DATETIME value, as a character string. If the result is numeric, such as 23 for the day, it is still returned as a character string. For example, the following statement displays the value May.

SELECT datename( month , '1987/05/02' )

DATETIME( expression )   Converts the expression into a timestamp. Conversion errors may be reported.

DAY( date-expr )   Returns a number from 1 to 31 corresponding to the day of the given date.

DAYNAME( date-expr )   Returns the name of the day from the supplied date expression. For example, with the date_order option set to the default value of ymd:

SELECT DAYNAME ('1987/05/02')

returns the value Saturday.

DAYS( datetime-expr )   Return the number of days since an arbitrary starting date.

DAYS( date-expr, date-expr )   Returns the number of days from the first date to the second date. The number may be negative. Hours, minutes and seconds are ignored.

DAYS( date-expr, integer-expr )   Add integer-expr days to the given date. If the integer-expr is negative, the appropriate number of days are subtracted from the date. Hours, minutes and seconds are ignored.

DOW( date-expr )   Returns a number from 1 to 7 representing the day of the week of the given date, with Sunday=1, Monday=2, and so on.

HOUR( datetime-expr )   Returns a number from 0 to 23 corresponding to the hour component of the given date.

HOURS( datetime-expr )   Return the number of hours since an arbitrary starting date and time.

HOURS( datetime-expr, datetime-expr )   Returns the number of whole hours from the first date/time to the second date/time. The number may be negative.

HOURS( datetime-expr, integer-expr )   Add integer-expr hours to the given date/time. If the integer-expr is negative, the appropriate number of hours are subtracted from the date/time.

MINUTE( datetime-expr )   Returns a number from 0 to 59 corresponding to the minute component of the given date/time.

MINUTES( datetime-expr )   Return the number of minutes since an arbitrary starting date and time.

MINUTES( datetime-expr, datetime-expr )   Returns the number of whole minutes from the first date/time to the second date/time. The number may be negative.

MINUTES( datetime-expr, integer-expr )   Add integer-expr minutes to the given date/time. If the integer-expr is negative, the appropriate number of minutes are subtracted from the date/time.

MONTH( date-expr )   Returns a number from 1 to 12 corresponding to the month of the given date.

MONTHNAME( date-expr )   Returns the name of the month from the supplied date expression. For example, with the date_order option set to the default value of ymd:

SELECT MONTHNAME ('1987/05/02')

returns the value May.

MONTHS( datetime-expr )   Return the number of months since an arbitrary starting date. This number is often useful for determining if two date/time expressions are on the same month in the same year.

MONTHS( invoice_sent ) = MONTHS( payment_received )

Note that comparing the MONTH function would be wrong if a payment were made 12 months after the invoice was sent.

MONTHS( date-expr, date-expr )   Returns the number of whole months from the first date to the second date. The number may be negative. Hours, minutes and seconds are ignored.

MONTHS( date-expr, integer-expr )   Add integer-expr months to the given date. If the new date is past the end of the month (such as MONTHS('1992-01-31', 1) ) the result is set to the last day of the month. If the integer-expr is negative, the appropriate number of months are subtracted from the date. Hours, minutes and seconds are ignored.

NOW( * )   Returns the current date and time. This is the historical syntax for CURRENT TIMESTAMP.

QUARTER( date-expr )   Returns the quarter from the supplied date expression. For example, with the date_order option set to the default value of ymd:

SELECT QUARTER ('1987/05/02')

returns the value 2.

SECOND( datetime-expr )   Returns a number from 0 to 59 corresponding to the second component of the given date.

SECONDS( datetime-expr )   Return the number of seconds since an arbitrary starting date and time.

SECONDS( datetime-expr, datetime-expr )   Returns the number of whole seconds from the first date/time to the second date/time. The number may be negative.

SECONDS( datetime-expr, integer-expr )   Add integer-expr seconds to the given date/time. If the integer-expr is negative, the appropriate number of seconds are subtracted from the date/time.

TODAY( * )   Returns today's date. This is the historical syntax for CURRENT DATE.

WEEKS( datetime-expr )   Return the number of weeks since an arbitrary starting date. (Weeks are defined as going from Sunday to Saturday, as they do in a North American calendar.) This number is often useful for determining if two dates are in the same week.

WEEKS( invoice_sent ) = WEEKS( payment_received )

WEEKS( date-expr, date-expr )   Returns the number of whole weeks from the first date to the second date. The number may be negative. Hours, minutes and seconds are ignored.

WEEKS( date-expr, integer-expr )   Add integer-expr weeks to the given date. If the integer-expr is negative, the appropriate number of weeks are subtracted from the date. Hours, minutes and seconds are ignored.

YEAR( date-expr )   Returns a 4 digit number corresponding to the year of the given date.

YEARS( date-expr )   Same as the YEAR function.

YEARS( date-expr, date-expr )   Returns the number of whole years from the first date to the second date. The number may be negative. Hours, minutes and seconds are ignored. For example, age can be calculated by

YEARS( birthdate, CURRENT DATE )

YEARS( date-expr, integer-expr )   Add integer-expr years to the given date. If the new date is past the end of the month (such as YEARS( '1992-02-29', 1 ) ) the result is set to the last day of the month. If the integer-expr is negative, the appropriate number of years are subtracted from the date. Hours, minutes, and seconds are ignored.

YMD( year-num, month-num, day-num )   Returns a date value corresponding to the given year, month, and day of the month. If the month is outside the range 1-12, the year is adjusted accordingly. Similarly, the day is allowed to be any integer: the date is adjusted accordingly. For example,

YMD( 1992, 15, 1 ) = 'Mar 1 1993'

YMD( 1992, 15, 1-1 ) = 'Feb 28 1993'

YMD( 1992, 3, 1-1 ) = 'Feb 29 1992'


Data type conversion functions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 40. Watcom-SQL Functions

Data type conversion functions

Purpose

Data type conversion functions convert values.

Syntax

Data type conversion function:

  CAST ( expression AS datatype )

| CONVERT ( datatype, expression [ , format-style ] )

 Description

The DATE, DATETIME, and DATEFORMAT functions which convert expressions to dates, timestamps, or strings based on a date format are listed in "Date and time functions". The STRING function, which converts expressions to a string, is discussed in "String functions".

SQL Anywhere carries out many type conversions automatically. For example, if a string is supplied where a numerical expression is required, the string is automatically converted to a number. For more information on automatic data type conversions carried out by SQL Anywhere, see "Data type conversions".

CAST( expression AS data-type )   Returns the value of expression, converted to the supplied data-type. If the length is omitted for character string types, SQL Anywhere chooses an appropriate length. If neither precision nor scale is specified for a DECIMAL conversion, SQL Anywhere selects appropriate values. For example:

CAST( '1992-10-31' AS DATE ) --ensure string is used

--as a DATE

CAST( 1 + 2 AS CHAR ) --SQL Anywhere chooses

--length

CAST( Surname AS CHAR(10) ) --useful for shortening

--strings

CONVERT( data-type, expression )   Returns the expression converted to data-type. The following is an example of this use of CONVERT:

SELECT CONVERT (VARCHAR(12), order_date )

FROM sales_order ;

CONVERT( data-type, expression, format-style )   For converting strings to date or time data types and vice versa, the format-style is a style code number describing the date format string to be used. The values of the format-style argument have the following meanings:

(yy)	(yyyy)	Output
-	-0 or 100	mon dd yyyy hh:miAM (or PM)
1	101	mm/dd/yy
2	102	yy.mm.dd
3	103	dd/mm/yy
4	104	dd.mm.yy
5	105	dd-mm-yy
6	106	dd mon yy
7	107	mon dd, yy
8	108	hh:mm:ss
-	9 or 109	mmm dd yyyy hh:mi:ss:mmmAM (or PM)
10	110	mm-dd-yy
11	111	yy/mm/dd
12	112	yymmdd
If no format-style argument is provided, Style Code 0 is used.


System functions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 40. Watcom-SQL Functions

System functions

Purpose

System functions return system information.

Syntax

System function:

  connection_property ( { integer-expr | string-expr }

              ... [ , integer-expr ] )

| datalength ( expression )

| db_id ( [ string-expr ] )

| db_name ( [ integer-expr ] )

| db_property ( { integer-expr | string-expr }

  ... [,{ integer-expr | string-expr }] )

| next_connection ( { NULL | string-expr } )

| next_database ( { NULL | string-expr } )

| property ( { integer-expr | string-expr } )

| property_name ( integer-expr )

| property_number ( string-expr )

| property_description ( { integer-expr | string-expr } )

 Description

Databases currently running on a server or engine are identified by a database name and a database id number. The db_id and db_name functions provide information on these values.

A set of system functions provides information about properties of a currently running database, or of a connection, on the database engine. These system functions take the database name or ID, or the connection name, as an optional argument to identify the database or connection for which the property is requested.

The available properties and their uses are described following the listing of the functions.

connection_property ( { property-id | property-name } [, connection-id ] )   Returns the value of the given property as a string. The current connection is used if the second argument is omitted.

datalength ( expression )   Returns the length of the expression in bytes. The expression is usually a column name. If the expression is a string constant, it must be enclosed in quotes. The following query displays the longest string in the company_name column of the customer table:

SELECT MAX( DATALENGTH( company_name ) )

FROM customer

db_id ( [database-name] )   Returns the database ID number. The supplied database_name must be a string expression; if it is a constant expression, it must be enclosed in quotes. If no database_name is supplied, the ID number of the current database is returned.

db_name ( [database-id] )   Returns the database name. The supplied database_id must be a numeric expression. If no database_id is supplied, the name of the current database is returned.

db_property ( { property-id | property-name } [, { database-id | database-name } ] )   Returns the value of the given property as a string. The current database is used if the second argument is omitted.

next_connection ( { NULL | connection-id } )   Returns the next connection number, or the first connection if parm is NULL.

next_database ( { NULL | database-id } )   Returns the next database number, or the first connection if parm is NULL.

property ( { property-number | property-name } )   Returns the value of the specified property as a string.

property_name ( property-number )   Returns the name of the property with the supplied property-number.

property_number ( property-name )   Returns the number of the property with the supplied property-name.

property_description ( { property-number | property-name } )   Returns a description of the property with the supplied property-name or property-number. The statistics and properties available are those in the following list. The list includes the name of each property, and a brief description. While each property does have a number as well as a name, the number is subject to change between releases of SQL Anywhere, and should not be used as a reliable identifier for a given property.

 Connection properties

 Properties available for the engine

 Properties available for each database


Connection properties
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 40. Watcom-SQL Functions

System functions

Connection properties

The following table lists properties available for each connection.

Descriptions

Property	Description
Async2Read	The number of rereads. A reread occurs when a read request for a page is received by the database IO subsystem while an asynchronous read IO operation has been posted to the operating system but has not completed.
AsyncRead	The number of pages that have been read asynchronously from disk.
AsyncWrite	The number of pages that have been written asynchronously to disk.
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.
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.
CacheWrite	The number of pages in the cache that have been modified.
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 SQL Anywhere, or is "local" for a connection without a SQL Anywhere Client.
CurrTaskSwitch	The number of current request context switches.
Cursors	The number of declared cursors that are currently being maintained by the engine.
CursorOpen	Open cursors is the number of open cursors that are currently being maintained by the engine.
DBNumber	The id number of the database.
DiskRead	The number of pages that have been read from file.
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.
DiskSyncRead	The number of pages that have been read synchronously from disk..
DiskSyncWrite	The number of pages that have been written synchronously to disk. It is the sum of all the other "Disk SyncWrites" counters.
DiskWaitRead	The number of times the engine has waited synchronously for the completion of a read IO operation which was originally issued as an asynchronous read. Waitreads often occur due to cache misses on systems that support asynchronous IO.
DiskWaitWrite	The number of times engine has waited synchronously for the completion of a write IO operation which was originally issued as an asynchronous write.
DiskWrite	The number of modified pages that have been written to disk.
FullCompare	The number of comparisons beyond the hash value in an index that have been performed.
HintUsed	The number of page-read operations that have been satisfied immediately from cache thanks to a earlier read hint.
IndAdd	The number of entries that have been added to indexes.
IndLookup	The number of entries that have been looked up in indexes.
LastIdle	The number of ticks between requests.
LastReqTime	The time at which the last request for the specified connection started.
LockTablePages	The number of pages used for the lock table.
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").
LogRewrite	The number of pages that were previously written to the transaction log (but were not full) that have been written to the transaction log again (but with more data added).
LogWrite	The number of pages that have been written to the transaction log.
Name	The database name.
NodeAddress	The node for the client in a client/server connection.
Number	The ID number of the connection.
Port	An application-specific number for each client machine, identifying the connection port.
PrepStmt	The number of prepared statements that are currently being maintained by the engine.
ProcessTime	The time since the start of the connection.
ReadHint	The number of read hints. A read hint is an asynchronous read operation for a page that the database engine is likely to need soon.
ReqType	A string for the type of the last request.
Rlbk	The number of Rollback requests that have been handled.
RollbackLogPages	The number of pages in the rollback log
SyncWriteChkpt	The number of pages that have been written synchronously to disk for a checkpoint.
SyncWriteExtend	The number of pages that have been written synchronously to disk while extending a database file.
SyncWriteFreeCurr	The number of pages that have been written synchronously to disk to free a page that cannot remain in the in-memory free list.
SyncWriteFreePush	The number of pages that have been written synchronously to disk to free a page that can remain in the in-memory free list.
SyncWriteLog	The number of pages that have been written synchronously to the transaction log.
SyncWriteRlbk	The number of pages that have been written synchronously to the rollback log.
SyncWriteUnkn	The number of pages that have been written synchronously to disk for a reason not covered by other "Disk SyncWrites" counters.
TaskSwitch	The number of times the current engine thread has been changed.
TaskSwitchCheck	The number of times the current engine thread has volunteered to give up the CPU to another engine thread.
UncommitOp	The number of uncommitted operations for the connection.
Userid	The user ID for the connection.
VoluntaryBlock	The number of engine threads that have voluntarily blocked on pending disk IO.
WaitReadCmp	The number of read requests associated with a full comparison (a comparison beyond the hash value in an index) that must be satisfied by a synchronous read operation.
WaitReadOpt	The number of read requests posted by the optimizer that must be satisfied by a synchronous read operation.
WaitReadSys	The number of read requests posted from the system connection that must be satisfied by a synchronous read operation. The system connection is a special connection used as the context before a connection is made and for operations performed outside of any client connection.
WaitReadTemp	The number of read requests for a temporary table that must be satisfied by a synchronous read operation.
WaitReadUnkn	The number of read requests from other sources that must be satisfied by a synchronous read operation.


Properties available for the engine
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 40. Watcom-SQL Functions

System functions

Properties available for the engine

The following table lists properties that apply across the engine as a whole.

Descriptions

Property	Description
ActiveReq	The number of engine threads that are currently handling a request.
Async2Read	The number of rereads. A reread occurs when a read request for a page is received by the database IO subsystem while an asynchronous read IO operation has been posted to the operating system but has not completed.
AsyncRead	The number of pages that have been read asynchronously from disk.
AsyncWrite	The number of pages that have been written asynchronously to disk.
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.
CacheWrite	The number of pages in the cache that have been modified.
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 engine has forced a flush of the disk cache. On NT and NetWare platforms, the disk cache does not need to be  when unbuffered (direct) IO is used.
CompanyName	The name of the company owning this software (Sybase, Inc.).
ContReq	The number of "CONTINUE" requests issued to the engine.
CurrIO	The current number of file IOs issued by the engine which have not yet completed.
CurrRead	The current number of file reads issued by the engine which have not yet completed.
CurrWrite	The current number of file writes issued by the engine which have not yet completed.
DiskRead	The number of pages that have been read from file.
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.
DiskSyncRead	The number of pages that have been read synchronously from disk.
DiskSyncWrite	The number of pages that have been written synchronously to disk. It is the sum of all the other "Disk SyncWrites" counters.
DiskWaitRead	The number of times the engine has waited synchronously for the completion of a read IO operation which was originally issued as an asynchronous read. Waitreads often occur due to cache misses on systems that support asynchronous IO.
DiskWaitWrite	The number of times engine has waited synchronously for the completion of a write IO operation which was originally issued as an asynchronous write.
DiskWrite	The number of modified pages that have been written to disk.
ExtendDBWrite	The number of pages by which the database file has been extended.
ExtendTempWrite	The number of pages by which temporary files have been extended.
FreeWriteCurr	The number of pages freed of those that cannot remain in the in-memory free list.
FreeWritePush	The number of pages freed of those that can remain in the in-memory free list.
FullCompare	The number of comparisons beyond the hash value in an index that have been performed.
HintUsed	The number of page-read operations that have been satisfied immediately from cache thanks to a earlier read hint.
IdleCheck	The number of times the engine's idle thread has become active to do idle writes, idle checkpoints, and so on.
IdleChkpt	The number of checkpoints completed by the engine's idle thread. An idle checkpoint occurs whenever the idle thread writes out the last dirty page in the cache.
IdleChkTime	The number of 100'ths of a second spent checkpointing during idle I/O.
IdleWrite	The number of disk writes that have been issued by the engine'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.
LegalCopyright	The Copyright string for the software.
LegalTrademarks	Trademark information for the software.
LockTablePages	The number of pages used to store lock information
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").
LogRewrite	The number of pages that were previously written to the transaction log (but were not full) that have been written to the transaction log again (but with more data added).
LogWrite	The number of pages that have been written to the transaction log.
MainHeapPages	The number of pages used for global engine data structures.
MapPages	The number of map pages used for accessing the lock table, frequency table, and table layout.
MaxIO	The maximum value that "Current IO" has reached.
MaxRead	The maximum value that "Current Reads" has reached.
MaxWrite	The maximum value that "Current Writes" has reached.
Name	The name of the engine or server.
PageRelocations	The number of relocatable heap pages read from the temporary file.
PendingReq	The number of new requests detected by the engine.
Platform	The operating system on which the software is running.
ProcedurePages	The number of relocatable heap pages used for procedures.
ProductName	The name of the software.
ProductVersion	The version of the software being run.
ReadHint	The number of read hints. A read hint is an asynchronous read operation for a page that the database engine is likely to need soon.
RelocatableHeapPages	The number of pages used for relocatable heaps (cursors, statements, procedures, triggers, views, etc.).
Req	The number of times the engine has been entered to allow it to handle a new request or continue processing an existing request.
RollbackLogPages	The number of pages in the rollback log.
SyncWriteChkpt	The number of pages that have been written synchronously to disk for a checkpoint.
SyncWriteExtend	The number of pages that have been written synchronously to disk while extending a database file.
SyncWriteFreeCurr	The number of pages that have been written synchronously to disk to free a page that cannot remain in the in-memory free list.
SyncWriteFreePush	The number of pages that have been written synchronously to disk to free a page that can remain in the in-memory free list.
SyncWriteLog	The number of pages that have been written synchronously to the transaction log.
SyncWriteRlbk	The number of pages that have been written synchronously to the rollback log.
SyncWriteUnkn	The number of pages that have been written synchronously to disk for a reason not covered by other "Disk SyncWrites" counters.
TriggerPages	The number of relocatable heap pages used for triggers.
UnschReq	The number of requests that are currently queued up waiting for an available engine thread.
ViewPages	The number of relocatable heap pages used for views.
VoluntaryBlock	The number of engine threads that have voluntarily blocked on pending disk IO.
WaitReadCmp	The number of read requests associated with a full comparison (a comparison beyond the hash value in an index) that must be satisfied by a synchronous read operation.
WaitReadOpt	The number of read requests posted by the optimizer that must be satisfied by a synchronous read operation.
WaitReadSys	The number of read requests posted from the system connection that must be satisfied by a synchronous read operation. The system connection is a special connection used as the context before a connection is made and for operations performed outside of any client connection.
WaitReadTemp	The number of read requests for a temporary table that must be satisfied by a synchronous read operation.
WaitReadUnkn	The number of read requests from other sources that must be satisfied by a synchronous read operation.


Properties available for each database
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 40. Watcom-SQL Functions

System functions

Properties available for each database

The following table lists properties available for each database on the server.

Descriptions

Property	Description
Alias	The database name.
ConnCount	The number of connections to the database.
File	The file name of the database root file, including path.
FileVersion	The version of the database file.
LogName	The file name of the transaction log, including path.
Name	The database name, or alias.
PageSize	The page size of the database, in bytes.


Miscellaneous functions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 40. Watcom-SQL Functions

Miscellaneous functions

Purpose

Miscellaneous functions perform operations on arithmetic, string or date/time expressions, including the return values of other functions.

Syntax

Miscellaneous function:

  ARGN ( integer-expr, expression [ , ...] )

| COALESCE ( expression, expression [ , ...] )

| ESTIMATE ( column-name [ , number [, relation-string ] ] )

| ESTIMATE_SOURCE ( column-name [, number [ , relation-string ] ]

| IFNULL ( expression, expression [ , expression ] )

| INDEX_ESTIMATE( column-name, number [ , relation-string ] )

| EXPERIENCE_ESTIMATE( column-name, number [ , relation-string ]) ]

| ISNULL ( expression, expression [ , ... ] )

| NUMBER ( * )

| PLAN ( string-expr )

| TRACEBACK ( * )

 Description

ARGN( integer-expr, expression [, ...] )   Using the value of integer-expr as n,  return the n'th argument (starting at 1) from the  remaining list of arguments.

COALESCE( expression, expression [ ... , expression] )   Returns the value of the first expression that is not NULL.

ESTIMATE( column-name [, number [, relation-string]] )   The relation-string must be a comparison operator enclosed in single quotes; the default is =. If number is specified, the function returns as a REAL the percentage estimate the query optimizer uses for the following condition:

column-name relation number

If number is not specified, the function returns the estimate used by the query-optimizer for the following condition:

column-name relation expression

The function returns NULL if the relation-string is not valid. For example, the following query returns the percentage estimate for employee ID numbers being greater than 200:

SELECT DISTINCT ESTIMATE( emp_id, 200, '>' )

FROM employee

ESTIMATE_SOURCE( column-name [, number [, relation-string]] )   This function is the same as the ESTIMATE function, except that it returns one of the strings Column, Value, or Index, where:

♦	Column means the estimate stored for the column

♦	Value means the estimate for a particular value, stored in the frequency table

♦	Index means the estimate derived from an index on the column

EXPERIENCE_ESTIMATE(column-name [, number [, relation-string]])   This function is the same as the ESTIMATE function, except that it looks only in the frequency table.

IFNULL( expression1, expression2 [, expression3] )   If the first expression is the NULL value, then the second expression is returned. Otherwise, the value of the third expression is returned if it was specified. If there was no third expression and the first expression is not NULL then the NULL value is returned.

INDEX_ESTIMATE( column-name [, number [, relation-string]] )   This function is the same as the ESTIMATE function, except that it looks only in an index.

ISNULL( expression, expression [ ... , expression] )   Same as the COALESCE function.

NUMBER( * )   Generates numbers starting at 1 for each successive row in the results of the query. Although the NUMBER(*) function is useful for generating primary keys when using the insert from select statement (see "INSERT statement"), the AUTOINCREMENT column is a preferred mechanism for generating sequential primary keys. For information on the AUTOINCREMENT default, see "CREATE TABLE statement".

You should not use the NUMBER( * ) function anywhere but in a select-list. If you do use NUMBER( * ) rather than the preferred AUTOINCREMENT, you should check your results carefully, as the behavior is not reliable in several circumstances. For example, including the function in a WHERE clause or a HAVING clause produces unpredictable results, and you should not include NUMBER( * ) in a UNION operation.

In Embedded SQL, care should be exercised when seeking a cursor that references a query containing a NUMBER(*) function. In particular, this function returns negative numbers when a database cursor is positioned relative to the end of the cursor (an absolute seek with a negative offset).

PLAN( string-expr )   Returns the optimization strategy of the SELECT statement string-expr as a string.

TRACEBACK( * )   Returns a string containing a traceback of the procedures  and triggers that were executing when the most recent  exception (error) occurred. This is useful for debugging  procedures and triggers. To use the traceback function, enter the following after an error occurs while executing a procedure.

SELECT TRACEBACK (*)


Watcom-SQL Statements
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

About this chapter

This chapter presents detailed descriptions of the SQL statements available in the Watcom-SQL language—one of two SQL dialects native to SQL Anywhere.

This chapter contains an alphabetical listing of all Watcom-SQL statements, including some that can only be used from Embedded SQL, and ISQL.

  For information on Transact-SQL support, see the chapters "Using Transact-SQL with SQL Anywhere" and "Transact-SQL Procedure Language".

Descriptions of SQL, ISQL and Embedded SQL statements, as well as the elements that make up those statements, are included in this chapter.

 ALLOCATE DESCRIPTOR statement

 ALTER DBSPACE statement

 ALTER PROCEDURE statement

 ALTER PUBLICATION statement

 ALTER REMOTE MESSAGE TYPE statement

 ALTER TABLE statement

 ALTER TRIGGER statement

 ALTER VIEW statement

 CALL statement

 CASE statement

 CHECKPOINT statement

 CLOSE statement

 COMMENT statement

 COMMIT statement

 Compound statements

 CONFIGURE statement

 CONNECT statement

 CREATE DATATYPE statement

 CREATE DBSPACE statement

 CREATE FUNCTION statement

 CREATE INDEX statement

 CREATE PROCEDURE statement

 CREATE PUBLICATION statement

 CREATE REMOTE MESSAGE TYPE statement

 CREATE SCHEMA statement

 CREATE SUBSCRIPTION statement

 CREATE TABLE statement

 CREATE TRIGGER statement

 CREATE VARIABLE statement

 CREATE VIEW statement

 DBTOOL statement

 Declaration section

 DECLARE CURSOR statement

 DECLARE TEMPORARY TABLE statement

 DEALLOCATE DESCRIPTOR statement

 DELETE statement

 DELETE (positioned) statement

 DESCRIBE statement

 DISCONNECT statement

 DROP statement

 DROP CONNECTION statement

 DROP OPTIMIZER STATISTICS statement

 DROP PUBLICATION statement

 DROP REMOTE MESSAGE TYPE statement

 DROP STATEMENT statement

 DROP VARIABLE statement

 DROP SUBSCRIPTION statement

 EXECUTE statement

 EXECUTE IMMEDIATE statement

 EXIT statement

 EXPLAIN statement

 FETCH statement

 FOR statement

 FROM clause

 GET DATA statement

 GET DESCRIPTOR statement

 GET OPTION statement

 GRANT statement

 GRANT CONSOLIDATE statement

 GRANT PUBLISH statement

 GRANT REMOTE statement

 HELP statement

 IF statement

 INCLUDE statement

 INPUT statement

 INSERT statement

 LEAVE statement

 LOAD TABLE statement

 LOOP statement

 MESSAGE statement

 NULL value

 OPEN statement

 OUTPUT statement

 PARAMETERS statement

 PASSTHROUGH statement

 PREPARE statement

 PREPARE TO COMMIT statement

 PUT statement

 READ statement

 RELEASE SAVEPOINT statement

 RESIGNAL statement

 RESUME statement

 RETURN statement

 REVOKE statement

 REVOKE CONSOLIDATE statement

 REVOKE PUBLISH statement

 REVOKE REMOTE statement

 ROLLBACK statement

 ROLLBACK TO SAVEPOINT statement

 ROLLBACK TRIGGER statement

 SAVEPOINT statement

 SELECT statement

 SET statement

 SET CONNECTION statement

 SET DESCRIPTOR statement

 SET OPTION statement

 SET SQLCA statement

 SIGNAL statement

 START DATABASE statement

 START ENGINE statement

 START SUBSCRIPTION statement

 STOP DATABASE statement

 STOP ENGINE statement

 STOP SUBSCRIPTION statement

 SYNCHRONIZE SUBSCRIPTION statement

 SYSTEM statement

 TRUNCATE TABLE statement

 UNION operation

 UNLOAD TABLE statement

 UPDATE statement

 UPDATE (positioned) statement

 VALIDATE TABLE statement

 WHENEVER statement


ALLOCATE DESCRIPTOR statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

ALLOCATE DESCRIPTOR statement

Function

To allocate space for a SQL descriptor area (SQLDA).

Syntax

ALLOCATE DESCRIPTOR descriptor-name

... [ WITH MAX {  integer | hostvar }  ]

Usage

Embedded SQL.

Permissions

None.

Side effects

None.

 Description

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

The 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.


ALTER DBSPACE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

ALTER DBSPACE statement

Function

To modify the characteristics of the main database file or an extra dbspace. To preallocate space for a database or for the transaction log.

Syntax

ALTER DBSPACE { dbspace-name | TRANSLOG }

...

  ADD number

| RENAME filename

Usage

Anywhere.

Permissions

Must have DBA authority. Must be the only connection to the database.

Side effects

Automatic commit.

 Description

Each database is held in one or more files. A dbspace is an internal name associated with each database file. ALTER DBSPACE modifies the main database file (also called the root file) or an extra dbspace. The dbspace names for a database are held in the SYSFILE system table. The default dbspace name for the root file of a database is SYSTEM.

An ALTER DBSPACE with the ADD clause is used to preallocate disk space to a dbspace. It extends the size of a dbspace by the number of pages given by number. The page size of a database is defined when the database is created.

The ALTER DBSPACE statement with the ADD clause allows database files to be extended in large amounts before the space is required, rather than the normal 32 pages at a time when the space is needed. This can improve performance for loading large amounts of data and also serves to keep the dbspace files more contiguous within the file system.

The ALTER DBSPACE statement with the special dbspace name TRANSLOG preallocates disk space to the transaction log. Preallocation improves performance if the transaction log is expected to grow quickly. You may want to use this feature if, for example, you are handling large amounts of binary large objects (blobs), such as bitmaps.

The preallocation is carried out by altering the special dbspace name TRANSLOG, as follows:

ALTER DBSPACE TRANSLOG ADD number

This extends the size of the transaction log by the number of pages specified.

If you move a database file other than the root file to a different filename, directory, or device, use the ALTER DBSPACE statement with RENAME to ensure that SQL Anywhere can find the file when the database is started.

When a multi-file database is started, the start line or ODBC data source description tells SQL Anywhere where to find the root database file. The root database file (which has the default dbspace name SYSTEM) holds the system tables, and SQL Anywhere looks in these system tables to find the location of the other dbspaces. SQL Anywhere then opens each of the other dbspaces.

Using ALTER DBSPACE with RENAME on a root file has no effect.


ALTER PROCEDURE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

ALTER PROCEDURE statement

Function

To replace a procedure with a modified version. You must include the entire new procedure in the ALTER PROCEDURE statement, and reassign user permissions on the procedure.

Syntax

ALTER PROCEDURE [ owner.]procedure-name ( [ parameter , ... ] )

...   [ RESULT ( result-column , ... ) ]

...   [ ON EXCEPTION RESUME ]

...   compound-statement

Parameters

parameter:

    parameter_mode parameter-name data-type

...     [ DEFAULT expression ]

   | SQLCODE

   | SQLSTATE

parameter_mode:

     IN

   | OUT

   | INOUT

result-column:

   column-name data-type

Usage

Anywhere.

Permissions

Must be the owner of the procedure or be DBA.

Side effects

Automatic commit.

 Description

The ALTER PROCEDURE statement is identical in syntax to the CREATE PROCEDURE statement except for the first word. The ALTER PROCEDURE statement replaces the entire contents of the CREATE PROCEDURE statement with the contents of the ALTER PROCEDURE statement. 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.


ALTER PUBLICATION statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

ALTER PUBLICATION statement

Function

To alter the definition of a SQL Remote publication.

Syntax

ALTER PUBLICATION [ owner.]publication-name

     ADD TABLE article-description

...   | MODIFY TABLE article-description

   | { DELETE | DROP } TABLE [ owner.]table-name

   | RENAME publication-name

Parameters

article-description:

table-name [ ( column-name, ... ) ]

...    [ WHERE search-condition ]

...    [ SUBSCRIBE BY expression ]

Usage

Anywhere. This statement is applicable only to SQL Remote.

Permissions

Must have DBA authority, or be owner of the publication. Requires exclusive access to all tables referred to in the statement.

Side effects

Automatic commit.

 Description

The ALTER PUBLICATION statement alters a SQL Remote 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.


ALTER REMOTE MESSAGE TYPE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

ALTER REMOTE MESSAGE TYPE statement

Function

To change 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-string

Parameters

message-system:

 MAP | FILE | VIM | SMTP

Usage

Anywhere. This statement is applicable only to SQL Remote.

Permissions

Must have DBA authority.

Side effects

Automatic commit.

 Description

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.

For the FILE link, the ALTER REMOTE MESSAGE TYPE statement also causes the Message Agent to look for incoming messages in the address given for each message type.


ALTER TABLE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

ALTER TABLE statement

Function

To modify a table definition.

Syntax

ALTER TABLE [ owner.]table-name

...

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

| ADD table-constraint

| MODIFY column-definition

| MODIFY column-name DEFAULT default-value

| MODIFY column-name [ NOT ] NULL

| MODIFY column-name CHECK NULL

| MODIFY column-name CHECK ( condition )

| { DELETE | DROP } column-name

| { DELETE | DROP } CHECK

| { DELETE | DROP } UNIQUE ( column-name, ... )

| { DELETE | DROP } PRIMARY KEY

| { DELETE | DROP } FOREIGN KEY role-name

| RENAME new-table-name

| RENAME column-name TO new-column-name

Parameters

column-definition:

column-name data-type [ NOT NULL ] [ DEFAULT default-value ]

column-constraint:

  UNIQUE

| PRIMARY KEY

| REFERENCES table-name [ ( column-name ) ] [ actions ]

| CHECK ( condition )

default-value:

  string

| number

| AUTOINCREMENT

| CURRENT DATE

| CURRENT TIME

| CURRENT TIMESTAMP

| NULL

| USER

table-constraint:

  UNIQUE ( column-name, ... )

| PRIMARY KEY ( column-name, ... )

| CHECK ( condition )

| foreign-key-constraint

foreign-key-constraint:

[ NOT NULL ] FOREIGN KEY [ role-name ] [ (column-name, ... ) ]

... REFERENCES table-name [ (column-name, ... ) ]

... [ actions ] [ CHECK ON COMMIT ]

actions:

[ ON UPDATE action ] [ ON DELETE action ]

action:

  CASCADE

| SET NULL

| SET DEFAULT

| RESTRICT

Usage

Anywhere.

Permissions

Must be the owner of the table or have DBA authority. Requires exclusive access to the table.

Side effects

Automatic commit. The MODIFY and DELETE options close all cursors for the current connection. The ISQL data window is also cleared.

 Description

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.

ADD column-definition   Add a new column to the table. The table must be empty to specify NOT NULL.

NULL values—SQL Anywhere optimizes the creation of columns which are allowed to contain the NULL value. The first column that is allowed to contain the NULL value allocates room for eight such columns, and initializes all eight to be the NULL value. (This requires no extra storage.) Thus, the next seven columns added require no changes to the rows of the table. Adding one more column will then allocate room for another eight such columns and then modify each row of the table to allocate the extra space. Consequently, seven out of eight column additions run quickly.

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 created by the CREATE TABLE statement or another ALTER TABLE statement.

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.

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.

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 Release 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 SQL Anywhere 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 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 the new-table-name. Note that any applications using the old table name will need to be modified. Also, any foreign keys which were automatically assigned the same name as 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.

ALTER TABLE will be 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 same table while the statement is being processed.

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.


ALTER TRIGGER statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

ALTER TRIGGER statement

Function

To replace a trigger definition with a modified version. You must include the entire new trigger definition in the ALTER TRIGGER statement.

Syntax

ALTER TRIGGER trigger-name trigger-time trigger-event [, 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 ] ]

Parameters

trigger-time:

BEFORE  |  AFTER  |  RESOLVE

trigger-event:

DELETE  |  INSERT  |  UPDATE  |  UPDATE OF column-list

Usage

Anywhere.

Permissions

Must be the owner of the table on which the trigger is defined, or be DBA.

Side effects

Automatic commit.

 Description

The ALTER TRIGGER statement is identical in syntax to the CREATE TRIGGER statement except for the first word. The ALTER TRIGGER statement replaces the entire contents of the CREATE TRIGGER statement with the contents of the ALTER TRIGGER statement.


ALTER VIEW statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

ALTER VIEW statement

Function

To replace a view definition with a modified version. You must include the entire new view definition in the ALTER VIEW statement, and reassign permissions on the view

Syntax

ALTER VIEW

... [ owner.]view-name [( column-name, ... )]

... AS select-without-order-by

... [ WITH CHECK OPTION ]

Usage

Anywhere.

Permissions

Must be owner of the view or have DBA authority.

Side effects

Automatic commit.

 Description

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 and CREATE VIEW were carried out, permissions on the view would have to be reassigned.


CALL statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

CALL statement

Function

To invoke a procedure.

Syntax

[variable = ] CALL procedure-name ( [ expression ,... ] )

[variable = ] CALL procedure-name ( [ parameter-name = expression ,... ] )

Usage

Anywhere.

Permissions

Must be the owner of the procedure, have EXECUTE permission for the procedure, or have DBA authority.

Side effects

None.

 Description

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.

All arguments are optional: 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, the parameter is set to NULL.

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 a value (as a status indicator, say) using the RETURN statement. You can save this return value in a variable using using the quality sign as an assignment operator:

CREATE VARIABLE returnval INT ;

returnval = CALL proc_integer ( arg1 = val1, ... )


CASE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

CASE statement

Function

Select execution path based on multiple cases.

Syntax

CASE value-expression

...   WHEN [ constant | NULL ] THEN statement-list ...

...   [ WHEN [ constant | NULL ] THEN statement-list ] ...

...   ELSE statement-list

...   END CASE

Usage

Procedures, triggers, and batches.

Permissions

None.

Side effects

None.

 Description

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. 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.


CHECKPOINT statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

CHECKPOINT statement

Function

To checkpoint the database.

Syntax

CHECKPOINT

Usage

Anywhere.

Permissions

Must have DBA authority to CHECKPOINT when you are running with multiple users over a LAN. For single-user, no authorization is required.

Side effects

None.

Description

The CHECKPOINT statement will checkpoint the database. Checkpoints are also performed automatically by the database engine. It is not normally required for an application to ever issue the CHECKPOINT statement. For a full description of checkpoints, see "Backup and Data Recovery".


CLOSE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

CLOSE statement

Function

To close a cursor.

Syntax

CLOSE cursor-name

Parameters

cursor-name:   identifier, or host-variable

Usage

Embedded SQL, procedures, triggers, and batches.

The host-variable format is for Embedded SQL only.

Permissions

The cursor must have been previously opened.

Side effects

None.

 Description

This statement closes the named cursor.


COMMENT statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

COMMENT statement

Function

To store a comment in the system tables for a database object.

Syntax

COMMENT ON

{

    COLUMN [ owner.]table-name.column-name

   | FOREIGN KEY [ owner.]table-name.role-name

   | INDEX [ owner.]index-name

   | PUBLICATION [ owner.]publication-name

   | PROCEDURE [ owner.]procedure-name

   | SUBSCRIPTION [ owner.]subscription-name

   | TABLE [ owner.]table-name

   | USER userid

   | TRIGGER [ owner.]trigger-name

   | VIEW [ owner.]view-name

}

IS comment

Parameters

comment:

{ string | NULL }

Usage

Anywhere.

Permissions

Must either be the owner of the database object being commented, or have DBA authority.

Side effects

Automatic commit.

Description

Several system tables have a column named Remarks that allows you to associate a comment with a database item (SYSUSERPERM, SYSTABLE, SYSCOLUMN, SYSINDEX, 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.

When adding a comment to an index or trigger, the owner is the owner of the table on which the index or trigger is defined.


COMMIT statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

COMMIT statement

Function

To make any changes to the database permanent.

Syntax

COMMIT [ WORK ]

Usage

Anywhere.

Permissions

Must be connected to the database.

Side effects

Closes all cursors that were not opened with the WITH HOLD option.

 Description

The COMMIT statement ends a logical unit of work (transaction) and makes all changes made during this transaction permanent in the database. A transaction is defined as the database work done between successful COMMIT and ROLLBACK statements on a single database connection.

The COMMIT statement is also used as the second phase of a two-phase commit operation. See "Coordinating transactions with multiple database engines" and "PREPARE TO COMMIT statement" for more information.

The changes committed are those made by the data manipulation statements: INSERT, UPDATE, and DELETE, as well as the ISQL load statement INPUT.

The data definition statements all do an automatic commit. They are:

♦	ALTER

♦	COMMENT

♦	CREATE

♦	DROP

♦	GRANT

♦	REVOKE

♦	SET OPTION

The COMMIT statement fails if SQL Anywhere 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 either the database option WAIT_FOR_COMMIT is set ON or a particular foreign key was defined with a CHECK ON COMMIT clause, the database engine will not check integrity until the COMMIT statement is executed. For a two-phase commit operation, these errors will be reported on the first phase (PREPARE TO COMMIT), not on the second phase (COMMIT).


Compound statements
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

Compound statements

Function

To specify a statement that groups other statements together.

Syntax

[ statement-label : ]

... BEGIN [ [ NOT ] ATOMIC ]

...   [ local-declaration ; ... ]

...   statement-list

...   [ EXCEPTION [ exception-case ... ] ]

... END [ statement-label ]

Parameters

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

Usage

Procedures, triggers, and batches.

Permissions

None.

Side effects

None.

 Description

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. Immediately following the BEGIN, a compound statement can have local declarations 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.

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 triggers 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 the chapter "Using Procedures, Triggers, and Batches".


CONFIGURE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

CONFIGURE statement

Function

To activate the ISQL configuration window.

Syntax

CONFIGURE

Usage

ISQL.

Permissions

None.

Side effects

None.

 Description

The CONFIGURE statement activates the ISQL configuration window. This window displays the current settings of all ISQL options. It does not display or allow you to modify database options or options for other software that are stored in the database. The SET OPTIONS statement (see "SET OPTION statement") allows you to set all options—ISQL, database and other options.

The TAB key can be used to change fields. If a hardware cursor appears in a field, then you are allowed to type a value for the option. If the hardware cursor does not appear, you can use the cursor up and down keys to select one of the allowed values. When you have changed the options, press ENTER to save the changes and exit, or ESCAPE to undo the changes and exit.

If you press ENTER and you have selected Save Options to Database then the options will be written to the SYSOPTION table in the database and the database engine will perform an automatic COMMIT. If you do not select Save Options to Database, then the options are set temporarily and remain in effect for the current database connection only.


CONNECT statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

CONNECT statement

Function

To establish a connection to a database.

Syntax

Syntax 1

CONNECT [ TO engine-name ]

   ... [ DATABASE database-name ]

   ... [ AS connection-name ]

   ... [ USER ] userid  [ IDENTIFIED BY password ]

Syntax 2

CONNECT USING connect-string

Parameters

engine-name:   identifier, string or host-variable

database-name:   identifier, string or host-variable

connection-name:   identifier, string or host-variable

userid:   identifier, string or host-variable

password:   identifier, string or host-variable

connect-string:   a valid connection string or host variable

Usage

ISQL and Embedded SQL

Permissions

None.

Side effects

None.

 Description

The CONNECT statement establishes a connection to the database identified by database-name running on the engine or server identified by engine-name.

Embedded SQL behavior   In Embedded SQL, if no engine-name is specified, the default local database engine will be assumed (the first database engine started). If a local database engine is not running and the SQL Anywhere Client (DBCLIENT) is running, the default server will be assumed (the server name specified when the client was started). If no database-name is specified, the first database on the given engine or server will be assumed.

ISQL behavior   If no database or engine is specified in the CONNECT statement, ISQL remains connected to the current database, rather than to the default engine and database. If a database name is specified without an engine name, ISQL will try to connect to the specified database on the current engine. If an engine name is specified without a database name, ISQL will connect to the default database on the specified engine. For example, in the following batch, 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 Embedded SQL, WHENEVER, SET SQLCA and some DECLARE statements do not generate code and thus may appear before the CONNECT statement in the source file.)

The user ID and password are used for checking the permissions on SQL statements. If the password or the user ID and password are not specified, the user will be prompted to type the missing information.

In Embedded SQL, the user ID and password are used for permission checks on all dynamic SQL statements. Static SQL statements use the user ID and password specified with the -l  option on the SQLPP statement line. If no -l option is given,  then the user ID and password of the CONNECT statement are used for static SQL statements also.

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 example, if you are connected to a database as DBA, you can connect without a password with the statement:

connect other_user_id

In Embedded SQL, you can connect without a password by using a host variable for the password and setting the value of the host variable to be the null pointer.

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.

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.

The dictionary clause allows you to specify the directory that contains the data dictionary you want to log in to (files *.DFF).

A database directory can also be specified. This specifies the directory or list of directories that contain the data files you will be accessing in the upcoming session (files *.DAT).

For Syntax 2, a connect string is a list of parameter settings of the form keyword=value. For a description of valid settings for the connection string, see "Database connection parameters". The connect string must be enclosed in single quotes.


CREATE DATATYPE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

CREATE DATATYPE statement

Function

To create a user-defined data type in the database.

Syntax

CREATE { DATATYPE | DOMAIN } [ AS ] domain-name data-type

... [ [ NOT ] NULL ]

... [ DEFAULT default-value ]

... [ CHECK ( condition ) ]

Parameters

domain-name:

identifier

data-type:

built-in data type, with precision and scale

Usage

Anywhere.

Permissions

Must have RESOURCE authority.

Side effects

Automatic commit.

 Description

User-defined data types are aliases for built-in data types, including precision and scale values where applicable. They improve convenience and encourage consistency in the database.

It is recommended that you use CREATE DOMAIN, rather than CREATE DATATYPE, as CREATE DOMAIN is the ANSI/ISO SQL3 term.

User-defined data types can have CHECK conditions and DEFAULT conditions associated with them, and you can indicate whether the data type permits NULL values or not. These conditions are inherited by any column defined on the data type. Any conditions explicitly specified on the column override the data type conditions.

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 user-defined data type name must be unique, and all users can access the data type without using the owner as prefix.

User-defined data types are objects within the database. Their names must conform to the rules for identifiers. User-defined data type names are always case insensitive, as are built-in data type names.

By default, user-defined data types allow NULLs unless the allow_nulls_by_default option is set to OFF. In this case, new user-defined data types by default do not allow NULLs. Any columns created on a user-defined data type either allow or do not allow NULLs depending on the setting of the user-defined data type at the time it was created, not on the current setting of the allow_nulls_by_default option. Any explicit setting of NULL or NOT NULL in the column definition overrides the user-defined data type setting.

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.

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 user-defined data type.


CREATE DBSPACE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

CREATE DBSPACE statement

Function

To create a new database file. This file may be on a different device.

Syntax

CREATE DBSPACE dbspace-name AS filename

Usage

Anywhere.

Permissions

Must have DBA authority.

Side effects

Automatic commit.

 Description

The CREATE DBSPACE statement creates a new database file. When a database is first initialized using DBINIT, 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 root file allowing the creation of databases larger than one physical device.

The dbspace-name is an internal name for the database file. The filename is the actual name of the database file, with a path where necessary.

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. When you are using a SQL Anywhere, the filename is a filename on the server machine. When you are using the SQL Anywhere Server for NetWare, the filename should use a volume name (not a drive letter) when an absolute directory is specified.

Each table, including its associated indexes, is contained entirely within one database file. The IN clause of the CREATE TABLE statement the dbspace into which a table is placed. Tables are put into the root database file by default.


CREATE FUNCTION statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

CREATE FUNCTION statement

Function

To create a new function in the database.

Syntax

CREATE FUNCTION [ owner.]function-name ( [ parameter , ... ] )

...   RETURNS data-type

... { EXTERNAL NAME library-call |

... [ ON EXCEPTION RESUME ]

... compound-statement }

Parameters

parameter:

parameter-name data-type

library-call:

'[operating-system:]function-name@library.dll; ...'

operating-system:

  OS2

| Windows3X

| Windows95

| WindowsNT

| NetWare

Usage

Anywhere.

Permissions

Must have RESOURCE authority.

Side effects

Automatic commit.

 Description

The CREATE FUNCTION statement creates (stores) 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 nonaggregate functions.

Parameter names must conform to the rules for other database identifiers such as column names. They must be one of the types supported by SQL Anywhere (see "SQL Anywhere Data Types"), and must be prefixed by the keyword IN, signifying that the argument is an expression that provides a value to the procedure.

A function using the EXTERNAL NAME clause is a wrapper around a call to an external dynamic link library, and is called an external stored procedure. An external stored procedure can have no clauses other than the EXTERNAL NAME clause following the RETURNS clause. For a description of external procedures, see "Calling external libraries from stored procedures".


CREATE INDEX statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

CREATE INDEX statement

Function

To create an index on a specified table. Indexes are used to improve database performance.

Syntax

CREATE [ UNIQUE ] INDEX index-name

... ON [ owner.]table-name

... ( column-name [ ASC | DESC ], ... )

... [ { IN | ON } dbspace-name ]

Usage

Anywhere.

Permissions

Must be the owner of the table or have DBA authority.

Side effects

Automatic commit.

 Description

The CREATE INDEX statement creates a sorted index on the specified columns of the named table. Indexes are automatically used by SQL Anywhere to improve the performance of queries issued to the database as well as for sorting queries where an ORDER BY clause is specified. Once an index is created, it is never referenced again except to delete it using the DROP INDEX statement.

UNIQUE constraint   The UNIQUE constraint ensures that there will not be two rows in the table with identical values in all the columns in the index.

Ascending or descending sorting   Columns are sorted in ascending (increasing) order unless descending (DESC) is explicitly specified. An index will be used by SQL Anywhere for both an ascending and a descending ORDER BY, no matter 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.

Index placement   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 of use mainly for large databases, to circumvent the limit of 2 GB per table.

Notes

♦	Index ownership   There is no way of specifying the index owner in the CREATE INDEX statement. Indexes are automatically owned by the owner of the table on which they are defined. 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. For databases created previous to release 5.5.01, the condition was more restrictive: that each index name must be unique for a given user ID.

♦	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   SQL 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.


CREATE PROCEDURE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

CREATE PROCEDURE statement

Function

To create a new procedure in the database.

Syntax

CREATE PROCEDURE [ owner.]procedure-name ( [ parameter , ... ] )

...   {

   [ RESULT ( result-column , ... ) ] [ ON EXCEPTION RESUME ]

...     compound-statement

   | EXTERNAL NAME library-call

   }

Parameters

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.dll; ...'

operating-system:

  OS2

| Windows3X

| Windows95

| WindowsNT

| NetWare

Usage

Anywhere.

Permissions

Must have RESOURCE authority.

Side effects

Automatic commit.

 Description

The CREATE PROCEDURE statement creates (stores) a procedure in the database. A procedure can be created for another user by specifying a  owner. A procedure is invoked with a CALL statement

  The body of a procedure consists of a compound statement. For information about compound statements, see "Compound statements".

Parameter names must conform to the rules for other database identifiers such as column names. They must be one of the types supported by SQL Anywhere (see "SQL Anywhere Data Types".), and must be prefixed by one of the keywords IN, OUT or INOUT. The keywords have the following meanings:

♦	IN   argument is an expression that provides a value to the procedure.

♦	OUT   argument is a variable that could be given a value by the procedure.

♦	INOUT   argument 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 no default value is supplied, the parameter is NULL. 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 constants can always be checked immediately after a procedure call to test the return status of the procedure. However, the SQLSTATE and SQLCODE special constant 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 sets

A procedure that returns result sets ("Returning results from procedures") may have a RESULT clause. The parenthesized list following the RESULT keyword defines the number of result columns and name and type. 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 Anywhere Data Types".

Some procedures can return different result sets, 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

These variable result set procedures 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.

♦	ODBC   Variable result set procedures can be used by ODBC applications. The proper description of the variable result sets is carried out by the ODBC driver.

♦	Open Client applications   Variable result set procedures can be used by Open Client applications using the Open Server Gateway. The proper description of the variable result sets is carried out by the Open Server Gateway.

♦	ISQL   ISQL does not support calling of variable result set procedures, and so cannot be used for testing this feature.

If your procedure does not return variable result sets, you should use a RESULT clause. The presence of this clause prevents ODBC and Open Client applications from re-describing the result set after a cursor is open.

External procedures

A procedure using the EXTERNAL NAME clause is a wrapper around a call to an external dynamic link library, and is called an external stored procedure. An external stored procedure can have no clauses other than the EXTERNAL NAME clause following the parameter list. For a description of external procedures, see "Calling external libraries from stored procedures".


CREATE PUBLICATION statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

CREATE PUBLICATION statement

Function

To create a publication for replication with SQL Remote.

Syntax

CREATE PUBLICATION [  owner.]publication-name

...    ( TABLE article-description,... )

Parameters

article-description:

table-name [ ( column-name, ... ) ]

...    [ WHERE search-condition ]

...    [ SUBSCRIBE BY expression ]

Usage

Anywhere. This statement is applicable only to SQL Remote.

Permissions

Must have DBA authority. Requires exclusive access to all tables referred to in the statement.

Side effects

Automatic commit.

 Description

The CREATE PUBLICATION statement creates a SQL Remote publication in the database. A publication can be created for another user by specifying an owner name.

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 extraction utility from a consolidated database automatically executes the correct CREATE PUBLICATION statement in the remote database.

Article   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.

SUBSCRIBE BY clause   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.

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 if to be received by all subscribers to the publication.

You can combine WHERE and SUBSCRIBE BY clauses in an article definition.


CREATE REMOTE MESSAGE TYPE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

CREATE REMOTE MESSAGE TYPE statement

Function

To identify a message-link and return address for outgoing messages from a database.

Syntax

CREATE REMOTE MESSAGE TYPE message-system

...   ADDRESS address-string

Parameters

message-system:

 MAP | FILE | VIM | SMTP

Usage

Anywhere. This statement is applicable only to SQL Remote.

Permissions

Must have DBA authority.

Side effects

Automatic commit.

 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 of the current directory if that is not set. You can override this setting on the GRANT CONSOLIDATE statement at the remote database.

For the FILE link, the CREATE REMOTE MESSAGE TYPE statement also causes the Message Agent to look for incoming messages in the address given for each message type.

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.


CREATE SCHEMA statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

CREATE SCHEMA statement

Function

Creates a collection of tables, views, and permissions for a database user.

Syntax

CREATE  SCHEMA  AUTHORIZATION userid

...

[

   create-table-statement

   | create-view-statement

   | grant-statement

],...

Usage

Anywhere

Transact-SQL Usage

You cannot use the CREATE SCHEMA statement in a Transact-SQL batch or procedure.

Permissions

Must have RESOURCE authority.

Side effects

Automatic commit.

 Description

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 of the statements contained in the CREATE SCHEMA statement fails, then 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 the CREATE SCHEMA statement can currently be executed by a user more than once, this is not recommended, and may not be supported in future releases.


CREATE SUBSCRIPTION statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

CREATE SUBSCRIPTION statement

Function

To create a subscription for a user to a publication.

Syntax

CREATE SUBSCRIPTION

TO publication-name [ ( string ) ]

... FOR userid

Usage

Anywhere. This statement is applicable only to SQL Remote.

Permissions

Must have DBA authority.

Side effects

Automatic commit.

 Description

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.


CREATE TABLE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

CREATE TABLE statement

Function

To create a new table in the database.

Syntax

CREATE [ GLOBAL TEMPORARY ] TABLE [ owner.]table-name

... (    { column-definition [ column-constraint ... ] | table-constraint }, ... )

... [ { IN | ON } dbspace-name ]

... [ ON COMMIT { DELETE | PRESERVE } ROWS ]

Parameters

column-definition:

column-name data-type [ NOT NULL ] [ DEFAULT default-value ]

column-constraint:

  UNIQUE

| PRIMARY KEY

| REFERENCES table-name [( column-name )] [ actions ]

| CHECK ( condition )

default-value:

  string

| number

| AUTOINCREMENT

| CURRENT DATE

| CURRENT TIME

| CURRENT TIMESTAMP

| NULL

| USER

| ( constant-expression )

table-constraint:

  UNIQUE ( column-name, ... )

| PRIMARY KEY ( column-name, ... )

| CHECK ( condition )

| foreign-key-constraint

foreign-key-constraint:

   [NOT NULL] FOREIGN KEY [role-name] [(column-name, ... )]

   ... REFERENCES table-name [(column-name, ... )]

   ... [ actions ] [ CHECK ON COMMIT ]

action:

ON { UPDATE | DELETE }

...{ CASCADE | SET NULL | SET DEFAULT | RESTRICT }

Usage

Anywhere.

Permissions

Must have RESOURCE authority. To create a table for another user, you must have DBA authority.

Side effects

Automatic commit.

 Description

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 not specified, the table is referred to as a base table. Otherwise, the table is a temporary table.

The IN clause is allowed only for base tables, and is used to specify in which database file the base table will be created. See "CREATE DBSPACE statement" for more information.

A created temporary table is a table that exists in the database like 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 only visible 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 only see its own rows. The rows of a temporary table are deleted when the connection ends.

The ON COMMIT clause is only allowed for temporary tables. By default, the rows of a temporary table are deleted on COMMIT.

The parenthesized list following the CREATE TABLE statement can contain the following clauses in any order:

column-name data-type [ NOT NULL ] [ DEFAULT default-value ]    Define a column in the table. Allowable data types are described in "SQL Anywhere Data Types". Two columns in the same table cannot have the same name.

If NOT NULL is specified, or if the column is in a UNIQUE or PRIMARY KEY constraint, the column cannot contain any NULL values. If a DEFAULT value is specified, it will be used as the value for the column in any INSERT statement which does not specify a value for the column. If no DEFAULT is specified, it is equivalent to DEFAULT NULL.

When using DEFAULT AUTOINCREMENT, the data type must be one of INTEGER, SMALLINT, FLOAT, or DOUBLE. 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.

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 doing an explicit insert of a row number less then the maximum, subsequent rows without explicit assignment are autoincremented with a value of one greater than the previous maximum.

The next value to be used for each column is stored as a long integer (4 bytes). Using values greater than (2**31 - 1), that is, large double or numeric values, may cause wraparound to negative values, and AUTOINCREMENT should not be used in such cases.

For performance reasons, it is highly recommended that DEFAULT AUTOINCREMENT only be used with columns defined as a PRIMARY KEY or with a UNIQUE constraint; or columns that are the first column of an index. This will allow the maximum value determined at startup time to be found without scanning the entire table.

Constant expressions that do not reference database objects are allowed in a DEFAULT clause, so that 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.

table-constraint   Table constraints help ensure the integrity of data in the database. There are four types of integrity constraints:

♦	Unique constraint   Identifies one or more columns that uniquely identify each row in the table.

♦	Primary key constraint   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.

♦	Foreign key constraint   restricts the values for a set of columns to match the values in a primary key or uniqueness constraint of another 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.

♦	Check constraint   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 male or female.

If a statement would cause changes to the database that would violate an integrity constraint, the statement is effectively not executed and an error is reported. (Effectively means that any changes made by the statement before the error was detected are undone.)

column-constraint   Column constraints are abbreviations for the corresponding table constraints. For example, the following 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.

 Integrity constraints


Integrity constraints
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

CREATE TABLE statement

Integrity constraints

column-definition UNIQUE or UNIQUE ( column-name, ... )    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.

Unique constraint versus unique index—There is a difference between a unique constraint and a unique index. Columns in a unique index are allowed to be NULL, while columns in a unique constraint are not. Also, the column referenced by a foreign key can be either a primary key or a column with a unique constraint. Unique indexes cannot be referenced, because they can include multiple NULLs.

column-definition PRIMARY KEY or PRIMARY KEY ( column-name, ... )   The primary key for the table will consist of the listed column(s), and none of the named column(s) can contain any NULL values. SQL Anywhere ensures that each row in the table will have a unique primary key value. A table can have only one PRIMARY KEY.

When the second form is used (PRIMARY KEY followed by a list of columns), the primary key is created including the columns in the order in which they are defined, not the order in which they are listed.

column-definition REFERENCES primary-table-name [(primary-column-name)]   The column is a foreign key for the primary key or a unique constraint in the primary table. Normally, a foreign key would be for a primary key rather than a unique constraint. If a primary column name is specified, it must match a column in the primary table which is subject to a unique constraint or primary key constraint, and that constraint must consist of only that one column. Otherwise the foreign key references the primary key of the second table.

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 ] FOREIGN KEY [role-name] [(...)] REFERENCES primary-table-name [(...)]   The table contains a foreign key for the primary key or a unique constraint in another table. Normally, a foreign key would be for a primary key rather than a unique constraint. (In this description, this other table will be called the primary table.)

If the primary table column names are not specified, then the primary table columns will be the columns in the table's primary key. If foreign key column names are not specified then the foreign key columns will have the same names as the columns in the primary table. If foreign key column names are specified, then the primary key column names must be specified, and the column names are paired according to position in the lists.

Any foreign key column not explicitly defined will automatically be 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 must be explicitly created.

A foreign key can be explicitly created to be NOT NULL. In this case, no row is allowed that is NULL for any column in the key. If NOT NULL is not explicitly stated, the foreign key is still automatically defined as NOT NULL when all the columns in the foreign key do not allow null values at the time the foreign key is created.

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:

♦	If there is no foreign key with a role name the same as the table name, then the table name is assigned as the role name.

♦	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.

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, update the corresponding foreign keys to match the new primary key value. When used with ON DELETE, deletes the rows from the 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 to the value specified by the column(s) DEFAULT clause, all the foreign key values that match the updated or deleted primary key value.

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. This was the only form of referential integrity prior to Watcom SQL Version 4.0 and is the default action if no action is specified.

The CHECK ON COMMIT clause causes the database to wait for a COMMIT before checking the integrity of this foreign key, overriding the setting of the WAIT_FOR_COMMIT database option. CHECK ON COMMIT delays only the RESTRICT referential integrity action; it does not delay any other referential integrity action such as CASCADE or SET NULL. You can have a foreign key declared with CHECK ON COMMIT and a CASCADE or SET NULL referential action. In this case, inserts can be done in the foreign table before the corresponding row is inserted in the primary table as long as the row is inserted before the COMMIT.

If you use the short form of CHECK ON COMMIT then RESTRICT is implied.

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.

column-definition CHECK ( condition ) or CHECK ( condition )    No row is allowed to fail the condition. If an INSERT or UPDATE statement would cause a row to fail the condition, the operation is not permitted and the effects of the statement are undone.

When is the change rejected?—The change is rejected only if the condition is FALSE; in particular, the change is allowed if the condition is UNKNOWN. (See "NULL value" and "Search conditions" for more information about TRUE, FALSE, and UNKNOWN conditions.)


CREATE TRIGGER statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

CREATE TRIGGER statement

Function

To create a new trigger in the database.

Syntax

CREATE TRIGGER trigger-name trigger-time trigger-event [, 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 ] ]

Parameters

trigger-time:

BEFORE  |  AFTER  |  RESOLVE

trigger-event:

DELETE  |  INSERT  |  UPDATE  |  UPDATE OF column-list

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.

 Description

The CREATE TRIGGER statement creates a trigger associated with a table in the database and stores the trigger in the database.

Triggers can be triggered by one or more of the following events:

♦	INSERT   Invoked whenever a new row is inserted into the table associated with the trigger.

♦	DELETE   Invoked whenever a row of the associated table is deleted.

♦	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 has been modified.

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.


CREATE VARIABLE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

CREATE VARIABLE statement

Function

To create a SQL variable.

Syntax

CREATE VARIABLE identifier data-type

Usage

Anywhere.

Permissions

None.

Side effects

None.

 Description

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 VARIABLE statement.

A variable can be used in a SQL statement anywhere a column name is allowed. If there is no column name that matches the identifier, SQL Anywhere checks to see if there is a variable that matches and uses its value.

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.

Variables created by CREATE VARIABLE can be used in any SQL statement or in any procedure or trigger.

Local variables in procedures and triggers are declared within a compound statement (see "Using compound statements").


CREATE VIEW statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

CREATE VIEW statement

Function

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.

Syntax

CREATE VIEW

...    [ owner.]view-name [( column-name, ... )]

...    AS select-without-order-by

...    [ WITH CHECK OPTION ]

Usage

Anywhere.

Permissions

Must have RESOURCE authority and SELECT permission on the tables in the view definition.

Side effects

Automatic commit.

 Description

The CREATE VIEW statement creates a view with the given name. A view can be created for another user by specifying the  owner. 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.

The columns in the view are given the names specified in the column name list. If the column name list is not specified, then the view columns are given names from the select list items. In order to use the names from the select list items, the items must be a simple column name or they must have an alias-name specified (see "SELECT statement").

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.

The WITH CHECK OPTION clause rejects any updates and inserts to the view that do not meet the criteria of the view as defined by its SELECT statement.

The SELECT statement must not have an ORDER BY clause on it. It may have a GROUP BY clause and may be a UNION.


DBTOOL statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

DBTOOL statement

Function

To invoke one of the database tools.

Syntax

DBTOOL

  alter-database

| alter-writefile

| backup-to

| compress-database

| create-database

| create-writefile

| dbinfo-database

| drop-database

| translate

| uncompress-database

| unload-collation

| unload-tables

| validate-tables

Parameters

alter-database:

ALTER DATABASE name

...   { NO [ TRANSACTION ] LOG

     | SET [ TRANSACTION ] LOG TO filename }

alter-writefile:

ALTER WRITEFILE name [ REFER TO dbname ]

backup-to:

BACKUP TO directory

...   {  [ DBFILE ] [ WRITE FILE ] [ [ TRANSACTION ] LOG ]

   | [ ALL FILES ] }

...   { [ RENAME [ TRANSACTION ] LOG ]

   | [ TRUNCATE [ TRANSACTION ] LOG ] }

...   [ NOCONFIRM ] USING connection-string

compress-database:

COMPRESS DATABASE filename [ TO filename ]

create-database:

CREATE DATABASE filename

...   { [ NO [ TRANSACTION ] LOG ]

   | [ [ TRANSACTION ] LOG TO filename ] }

...    [ { IGNORE | RESPECT } CASE ]

...   [ PAGE SIZE n ] [ COLLATION name ]

...   [ ENCRYPT ] [ TRAILING SPACES ]

create-writefile:

CREATE WRITEFILE name FOR DATABASE name

...   [ [ TRANSACTION ] LOG TO logname ] [ NOCONFIRM ]

dbinfo-database:

DBINFO DATABASE filename

TO filename [ [ WITH ] PAGE USAGE ]

drop-database:

DROP DATABASE name [ NOCONFIRM ]

translate:

TRANSLATE [ TRANSACTION ] LOG FROM logname

...   [ TO sqlfile ] [ WITH ROLLBACKS ]

...   | [ USERS u1, u2, ... , un ]

   | [ EXCLUDE USERS u1, u2, ... , un ]

...   [ LAST CHECKPOINT ] [ ANSI ] [ NOCONFIRM ]

uncompress-database:

UNCOMPRESS DATABASE filename [ TO filename ] [ NOCONFIRM ]

unload-collation:

UNLOAD COLLATION [ name ] TO filename

...   USING connection-string

...   [ EMPTY MAPPINGS ] [ HEX | HEXADECIMAL ] [ NOCONFIRM ]

unload-tables:

UNLOAD TABLES TO directory [ RELOAD FILE TO filename ]

...     [ DATA | SCHEMA ]

...   [ UNORDERED ] [ VERBOSE ] USING connection-string

validate-tables:

VALIDATE TABLES [ t1, t2, ..., tn ] USING connection-string

connection-string:

string of connection parameters

Usage

ISQL.

Permissions

None.

Side effects

None.

 Description

The DBTOOL statement invokes one of the database utilities. All of the database utilities are available without leaving ISQL.

The following table lists the database utility invoked by each DBTOOL statement.

  For more information on the database utility programs, see the chapter "SQL Anywhere Components".

Statement	Database tool
DBTOOL ALTER DATABASE	DBLOG
DBTOOL ALTER WRITEFILE	DBWRITE
DBTOOL BACKUP TO	DBBACKUP
DBTOOL COMPRESS DATABASE	DBSHRINK
DBTOOL CREATE DATABASE	DBINIT
DBTOOL CREATE WRITEFILE	DBWRITE
DBTOOL DBINFO DATABASE	DBINFO
DBTOOL DROP DATABASE	DBERASE
DBTOOL TRANSLATE	DBTRAN
DBTOOL UNCOMPRESS DATABASE	DBEXPAND
DBTOOL UNLOAD COLLATION	DBCOLLAT
DBTOOL UNLOAD TABLES	DBUNLOAD
DBTOOL VALIDATE TABLES	DBVALID


Declaration section
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

Declaration section

Function

To declare host variables in an Embedded SQL program. Host variables are used to exchange data with the database.

Syntax

EXEC SQL BEGIN DECLARE SECTION;

C declarations

EXEC SQL END DECLARE SECTION;

Usage

Embedded SQL.

Permissions

None.

 Description

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 "Host variables" for more information.


DECLARE CURSOR statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

DECLARE CURSOR statement

Function

To declare a cursor. Cursors are the primary means for retrieving data from the database using Embedded SQL.

Syntax

DECLARE cursor-name

...    [  UNIQUE

     | SCROLL

     | NO SCROLL

     | DYNAMIC SCROLL

     | INSENSITIVE  ]

...     CURSOR FOR statement

      | CURSOR FOR statement-name

   ...   [ FOR UPDATE | FOR READ ONLY ]

Parameters

cursor-name:   identifier

statement-name:   identifier, or host-variable

Usage

Embedded SQL, procedures, triggers, and batches.

The statement-name and host-variable formats are for Embedded SQL only.

Permissions

None.

Side effects

None.

 Description

The DECLARE CURSOR statement declares a cursor with the specified name for a SELECT statement or a CALL statement.

When a cursor is declared UNIQUE, the query is forced to return all the columns required to uniquely identify each row. Often this will mean ensuring that all of the columns in the primary key or a uniqueness table constraint are returned. Any columns that are required but were not specified will be added. 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, since it was required to uniquely identify the rows

A cursor declared FOR READ ONLY may not be used in an UPDATE (positioned) or a DELETE (positioned) operation. FOR UPDATE is the default.

A cursor declared NO SCROLL is restricted to FETCH NEXT and FETCH RELATIVE 0 seek operations. A cursor declared SCROLL or DYNAMIC SCROLL can use all formats of the FETCH statement. DYNAMIC SCROLL is the default.

SCROLL cursors behave differently from DYNAMIC SCROLL cursors when the rows in the cursor are modified or deleted after the first time the row is read. SCROLL cursors have more predictable behavior when changes happen.

Each row fetched in a SCROLL cursor is remembered. If one of these rows is deleted, either by your program or by another program in a multiuser environment, it creates a "hole" in the cursor. If you fetch the row at this "hole" with a SCROLL cursor, SQL Anywhere returns the error SQLE_NO_CURRENT_ROW indicating that the row has been deleted, and leaves the cursor positioned on the "hole". (A DYNAMIC SCROLL cursor will just skip the "hole" and retrieve the next row.) This allows your application to remember row positions within a cursor and be assured that these positions will not change. For example, an application could remember that Cobb is the second row in the cursor for SELECT * FROM employee. If the first employee (Whitney) is deleted while the SCROLL cursor is still open, FETCH ABSOLUTE 2 will still position on Cobb while FETCH ABSOLUTE 1 will return SQLE_NO_CURRENT_ROW. Similarly, if the cursor is on Cobb, FETCH PREVIOUS will return SQLE_NO_CURRENT_ROW.

In addition, a fetch on a SCROLL cursor will return the warning SQLE_ROW_UPDATED_WARNING if the row has changed since it was last read. (The warning only happens once; fetching the same row a third time will not produce the warning.) Similarly, an UPDATE (positioned) or DELETE (positioned) statement on a row that has been modified since it was last fetched will return the error SQLE_ROW_UPDATED_SINCE_READ and abort the statement. An application must FETCH the row again before the UPDATE or DELETE will be permitted. Note that an update to any column will cause the warning/error, even if the column is not referenced by the cursor. For example, a cursor on Surname and Initials would report the update even if only the Birthdate column were modified. These update warning and error conditions will not occur in bulk operations mode (-b database engine statement line switch) when row locking is disabled. See "Tuning bulk operations".

SQL Anywhere maintains more information about SCROLL cursors than DYNAMIC SCROLL cursors; thus, DYNAMIC SCROLL cursors are more efficient and should be used unless the consistent behavior of SCROLL cursors is required. There is no extra overhead in SQL Anywhere for DYNAMIC SCROLL cursors versus NO SCROLL cursors.

Scroll cursors—The behavior of SCROLL cursors has changed since Watcom SQL 3.0. The SCROLL cursors in Watcom SQL 3.0 were equivalent to DYNAMIC SCROLL cursors now. Cursors declared with the default scrolling behavior will not have changed since the old default behavior was the SCROLL and the new default behavior is DYNAMIC SCROLL.

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.

INSENSITIVE cursors make it easier to write an application that deals with cursors, since you only have to worry about changes you make explicitly to the cursor; you do not have to worry about actions taken by other users or by other parts of your application.

INSENSITIVE cursors can be expensive if the cursor is on a lot of rows. Also, INSENSITIVE cursors are not affected by ROLLBACK or ROLLBACK TO SAVEPOINT; the ROLLBACK is not an operation on the cursor that changes the cursor contents.

INSENSITIVE cursors meet the ODBC requirements for static cursors.

Embedded SQL

Statements are named using the PREPARE statement. Cursors can be declared only for a prepared SELECT or CALL.

The DECLARE cursor statement does not generate any C code.

Cursor-name is a string and is supplied by the programmer.


DECLARE TEMPORARY TABLE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

DECLARE TEMPORARY TABLE statement

Function

To declare a local temporary table.

Syntax

DECLARE LOCAL TEMPORARY TABLE table-name

... ( { column-definition [ column-constraint ... ] | table-constraint }, ... )

... [   | ON COMMIT DELETE ROWS       |  ]

   | ON COMMIT PRESERVE ROWS  |

Usage

Embedded SQL, procedures, triggers, and batches.

Permissions

Must have RESOURCE authority.

Side effects

None.

 Description

The DECLARE LOCAL TEMPORARY TABLE statement declares a temporary table. See "CREATE TABLE statement" for definitions of column-definition, column-constraint, and table-constraint.

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.

By default, the rows of a temporary table are deleted on COMMIT.


DEALLOCATE DESCRIPTOR statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

DEALLOCATE DESCRIPTOR statement

Function

Frees memory associated with a SQL descriptor area.

Syntax

DEALLOCATE DESCRIPTOR descriptor-name

...

Usage

Embedded SQL.

Permissions

None.

Side effects

None.

 Description

Frees all memory associated with a descriptor area, including the data items, indicator variables, and the structure itself.


DELETE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

DELETE statement

Function

To delete rows from the database.

Syntax

DELETE [FROM] [ owner.]table-name

...    [FROM table-list]

...    [WHERE search-condition]

Usage

Anywhere.

Permissions

Must have DELETE permission on the table.

Side effects

None.

 Description

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.

  For a full description of the FROM clause and joins, see "FROM clause".

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.

Correlation name resolution

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_1 in the second from clause. In this case, there is no way of identifying which instance the first FROM clause should be identified with. The usual rules of correlation names apply, and table_1 in the first FROM clause is identified with neither instance in the second clause: there are three instances of table_1 in the statement.


DELETE (positioned) statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

DELETE (positioned) statement

Function

To delete the data at the current location of a cursor.

Syntax

DELETE [ FROM table-spec ]

...WHERE CURRENT OF cursor-name

Parameters

cursor-name:   identifier, or host-variable

table-spec: [ owner.]correlation-name ]

owner:   identifier

Usage

Embedded SQL, procedures, triggers, and batches.

The host-variable format is for Embedded SQL only.

Permissions

Must have DELETE permission on tables used in the cursor.

Side effects

None.

 Description

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.

Name resolution

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, the table-spec value is first matched against any correlation names.

♦	If a correlation name exists, the table-spec value is identified with the correlation name.

♦	If a correlation name does not exist, the table-spec value must be unambiguously identifiable as a table name in the cursor.

♦	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.

♦	The positioned DELETE statement can be used on a cursor open on a view as long as the view is updatable.


DESCRIBE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

DESCRIBE statement

Function

To get information about the host variables required to store data retrieved from the database or host variables used to pass data to the database.

Syntax

DESCRIBE

... [   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

Parameters

long-name-spec:

OWNER.TABLE.COLUMN | TABLE.COLUMN | COLUMN

statement-name:   identifier, or host-variable

cursor-name:   declared cursor

sqlda-name:   identifier

Usage

Embedded SQL.

Permissions

None.

Side effects

None.

 Description

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 describing a statement, 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 function alloc_sqlda).

If describing a cursor, the cursor must have been previously declared. The default action is to describe the OUTPUT. Only SELECT statements and CALL statements have OUTPUT. A DESCRIBE OUTPUT on any other statement will indicate no output by setting the sqld field of the SQLDA to zero.

SELECT   The DESCRIBE OUTPUT statement fills in the data type and length in the SQLDA for each select list item. 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.

When 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.

CALL   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 will also put the number of INOUT or OUT parameters in the sqld field of the SQLDA.

CALL (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.

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 will fill in the name fields in the SQLDA with the bind variable names. DESCRIBE INPUT will also put 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.

DESCRIBE ALL allows you to describe INPUT and OUTPUT with one request to the database engine. This has a performance benefit in a multiuser environment. 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.

Retrieving long column 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.

The default specification for the long names is TABLE.COLUMN.

Describing variable result sets

The WITH VARIABLE RESULT statement 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 engine 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.

 For more information on the use of the SQLDA structure, see "The SQL descriptor area (SQLDA)".


DISCONNECT statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

DISCONNECT statement

Function

To drop a connection with the database.

Syntax

DISCONNECT

  connection-name

| [ CURRENT ]

| ALL

Parameters

connection-name:   identifier, string or host-variable.

Usage

ISQL.

Permissions

None.

Side effects

None.

 Description

The DISCONNECT statement drops a connection with the database engine and releases all resources used by it. If the connection to be dropped was named on the CONNECT statement, then 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.


DROP statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

DROP statement

Function

To remove objects from the database.

Syntax

DROP

 { DATATYPE | DOMAIN } datatype-name

| DBSPACE dbspace-name

| INDEX [[owner].table-name.]index-name

| TABLE [ owner.]table-name

| VIEW [ owner.]view-name

| PROCEDURE [ owner.]procedure-name

| FUNCTION [ owner.]function-name

| TRIGGER [[ owner.]table-name.]trigger-name

Usage

Anywhere.

Permissions

For DROP DBSPACE, must have DBA authority and must be the only connection to the database.

For DROP TRIGGER, must have ALTER permissions on the table.

For others, must be the owner of the object, or have DBA authority.

Side effects

Automatic commit. Clears the Data window in ISQL. DROP TABLE and DROP INDEX close all cursors for the current connection.

 Description

The DROP statement removes the definition of the indicated database structure. If the structure is a dbspace, then 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 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 user-defined data type 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.


DROP CONNECTION statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

DROP CONNECTION statement

Function

To drop a connection to the database, belonging to any user.

Syntax

DROP CONNECTION connection-id

Usage

Anywhere. You must be connected to the same database on the same server as the connection ID to execute this statement.

Permissions

Must have DBA authority.

Side effects

None.

 Description

The DROP CONNECTION statement disconnects a user from the database by dropping the connection to the database.

The connection-id for the connection is obtained 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' )


DROP OPTIMIZER STATISTICS statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

DROP OPTIMIZER STATISTICS statement

Function

To reset optimizer statistics.

Syntax

DROP OPTIMIZER STATISTICS

Usage

Anywhere.

Permissions

Must have DBA authority.

Side effects

None.

Description

The DROP OPTIMIZER STATISTICS statement resets optimizer statistics. The SQL Anywhere optimizer maintains statistics as it evaluates queries and uses these statistics to make better decisions optimizing subsequent queries. These statistics are stored permanently in the database. The DROP OPTIMIZER STATISTICS statement resets these statistics to default values. This statement is most useful when first learning about the optimizer. It helps to better understand the process used by the optimizer.


DROP PUBLICATION statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

DROP PUBLICATION statement

Function

To drop a SQL Remote publication.

Syntax

DROP PUBLICATION [ owner.]publication-name

Usage

Anywhere. This statement is applicable only to SQL Remote.

Permissions

Must have DBA authority.

Side effects

Automatic commit. All subscriptions to the publication are dropped.

 Description

The DROP PUBLICATION statement drops an existing publication from the database.

Publication definitions are held at both consolidated and remote databases in a SQL Remote installation.


DROP REMOTE MESSAGE TYPE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

DROP REMOTE MESSAGE TYPE statement

Function

To delete a message type definition from a database.

Syntax

DROP REMOTE MESSAGE TYPE message-system

Parameters

message-system:

 MAP | FILE | VIM | SMTP

Usage

Anywhere. This statement is applicable only to 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.

 Description

The statement removes a message type from a database.


DROP STATEMENT statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

DROP STATEMENT statement

Function

To free statement resources.

Syntax

DROP STATEMENT [ owner.]statement-name

Parameters

statement-name:   identifier, or host-variable

Usage

Embedded SQL.

Permissions

Must have prepared the statement.

Side effects

None.

 Description

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.


DROP VARIABLE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

DROP VARIABLE statement

Function

To eliminate a SQL variable.

Syntax

DROP VARIABLE identifier

Usage

Anywhere.

Permissions

None.

Side effects

None.

 Description

The DROP VARIABLE statement eliminates a SQL variable previously created using the CREATE VARIABLE statement. Variables will be automatically eliminated when the database connection is released. However, variables are often used for large objects. Thus, eliminating them after use may free up significant resources (primarily disk space).


DROP SUBSCRIPTION statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

DROP SUBSCRIPTION statement

Function

To drop a subscription for a user from a publication.

Syntax

DROP SUBSCRIPTION TO publication-name [ ( string ) ]

...    FOR userid,...

Usage

Anywhere. This statement is applicable only to SQL Remote.

Permissions

Must have DBA authority.

Side effects

Automatic commit.

 Description

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.


EXECUTE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

EXECUTE statement

Function

To execute a SQL statement.

Syntax

Syntax 1

EXECUTE statement-name

...   [ USING DESCRIPTOR sqlda-name

   |  USING host-variable-list  ]

...   [  INTO DESCRIPTOR into-sqlda-name

   |   INTO into-host-variable-list ]

...    [ ARRAY :nnn ]

Parameters

statement-name:   identifier, or host-variable

sqlda-name:   identifier

into-sqlda-name:   identifier

Syntax 2

EXECUTE IMMEDIATE statement

statement:   string, or host-variable

Usage

Embedded SQL.

Permissions

Permissions are checked on the statement being executed.

Side effects

None.

 Description

Format 1 executes 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), then either the sqlda-name must specify a C variable which is a pointer to an SQLDA containing enough descriptors for all bind variables occurring in the statement, or the bind variables must be supplied in the host-variable-list.

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 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.

OUTPUT from a SELECT statement or a CALL statement is put either into the variables in the variable list or into 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.

If EXECUTE is used with an INSERT statement, the inserted row is returned in the second descriptor. For example, when using auto-increment primary keys or when using 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 assigned to the row. The same thing can be achieved by using @@identity with auto-increment keys.

Format 2 is 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.

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 "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.


EXECUTE IMMEDIATE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

EXECUTE IMMEDIATE statement

Function

To enable dynamically constructed statements to be executed from within a procedure.

Syntax

Syntax 1:   EXECUTE IMMEDIATE string-expression

Syntax 2:   EXECUTE ( string-expression )

For information about the Embedded SQL EXECUTE IMMEDIATE statement, see "EXECUTE statement".

Usage

Procedures, triggers, and batches

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.

Side effects

None. However, if the statement is a data definition statement with an automatic commit as a side effect, then that commit does take place.

 Description

The EXECUTE IMMEDIATE statement extends the range of statements that can be executed from within procedures and triggers. It allows dynamically prepared statements to be executed, 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.


EXIT statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

EXIT statement

Function

To leave ISQL.

Syntax

 EXIT   |    QUIT   |    BYE

Usage

ISQL.

Permissions

None.

Side effects

Will do a commit if option COMMIT_ON_EXIT is ON (default); otherwise will do a rollback.

 Description

Leave the ISQL environment and return to the operating system. This will close your connection with the database. Before doing so, ISQL will perform a COMMIT operation if the COMMIT_ON_EXIT option is ON. If the option is OFF, ISQL will perform a ROLLBACK. The default action is to COMMIT any changes you have made to the database.


EXPLAIN statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

EXPLAIN statement

Function

To retrieve a text specification of the optimization strategy used for a particular cursor.

Syntax

EXPLAIN PLAN FOR CURSOR cursor-name INTO host-variable

...     INTO host-variable

   | USING DESCRIPTOR sqlda-name

Parameters

cursor-name:   identifier, or host-variable

sqlda-name:   identifier

Usage

Embedded SQL.

Permissions

Must have opened the named cursor.

Side effects

None.

 Description

The EXPLAIN statement retrieves a text representation of the optimization strategy for the named cursor. The cursor must be previously declared and opened.

The host-variable or SQLDA variable must be of string type. The optimization string specifies in what order the tables are being searched and also which indexes are being used for the searches if any. This string can be quite long, but most optimization strings will fit into 300 characters.

The format of this string is, in general:

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 engine. 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) then the letters "seq" will appear for the index name. If a particular SQL SELECT statement involves subqueries, then a colon (:) will separate each subquery's optimization string. These subquery sections will appear in the order that the database engine will execute 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".


FETCH statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

FETCH statement

Function

To reposition a cursor and then get data from it.

Syntax

FETCH

{

  NEXT

| PRIOR

| FIRST

| LAST

| ABSOLUTE row-count

| RELATIVE row-count

}

... cursor-name

... [   | INTO host-variable-list   | ]

      | USING DESCRIPTOR sqlda-name|

      | INTO variable-list|

   ...   [ PURGE ] [ BLOCK n ]

   ...   [ FOR UPDATE ] [ ARRAY fetch-count ]

Parameters

cursor-name:   identifier, or host-variable

sqlda-name:   identifier

host-variable-list:   may contain indicator variables

row-count:   number or host variable

fetch-count:   integer or host variable

Usage

Embedded SQL, procedures, triggers, and batches..

The following clauses are for use in Embedded SQL only:

♦	USING DESCRIPTOR sqlda-name

♦	INTO host-variable-list

♦	PURGE

♦	BLOCK n

♦	ARRAY fetch-count

♦	Use of host-variable in cursor-name and row-count.

The INTO variable-list clause is for use in procedures and triggers only:

Permissions

The cursor must be opened and the user must have SELECT permission on the tables referenced in the declaration of the cursor.

Side effects

None.

 Description

The FETCH statement retrieves one row from the named cursor.

The ARRAY clause allows so-called wide fetches, which retrieve more than one row at a time, and which may improve performance.

The cursor must have been previously opened.

One or more rows from the result of the SELECT statement is put either into the variables in the variable list or into the program data areas described by the named SQLDA. In either case, the correspondence is one to one from the select list to either the host variable list or the SQLDA descriptor array.

The INTO clause is optional. If it is not specified, then the FETCH statement positions the cursor only (see the following paragraphs).

An optional positional parameter can be specified that allows the cursor to be moved before a row is fetched. The default is NEXT which 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 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.

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 is a short form for ABSOLUTE 1. LAST is a short form for ABSOLUTE -1.

The OPEN statement initially positions the cursor before the first row.

If the fetch includes a positioning parameter and the position is outside the allowable cursor positions, then the SQLE_NOTFOUND warning is issued.

Cursor positioning problems—Inserts and some updates to DYNAMIC SCROLL cursors can cause problems with cursor positioning. The database engine will 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 will not appear at all until the cursor is closed and opened again.
With SQL Anywhere, this occurs if a temporary table had to be created to open the cursor (see "Temporary tables used 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).

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 engine to put a write lock on the row. The lock will be held until the end of the current transaction. See "How locking works".

Using the FETCH statement in Embedded SQL

The 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, then the DECLARE statement actually generates code and thus must be executed before the FETCH statement.

In the multiuser environment, rows may be fetched by the client more than one at a time. Note that in QNX, the client is linked into the application so this will always happen by default. This is referred to as block fetching 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 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 PURGE clause 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.

If the SQLSTATE_NOTFOUND warning is returned on the fetch, then the sqlerrd[2] field of the SQLCA (SQLCOUNT) will contain the number of rows that the attempted fetch exceeded the allowable cursor positions. (A cursor can be on a row, before the first row or after the last row.) 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 will be positive if the attempted fetch was further beyond the end of the cursor, and negative if the attempted fetch was further before the beginning of the cursor.

After successful execution of the fetch statement, the sqlerrd[1] field of the SQLCA (SQLIOCOUNT) will be incremented by the number of input/output operations required to perform the fetch. This field is actually incremented on every database statement.

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.

The engine returns in SQLCOUNT the number of records fetched and always returns a SQLCOUNT greater than zero unless there is an error. Older versions of the engine or server only return a single row and the SQLCOUNT is set to zero. Thus a SQLCOUNT of zero with no error condition indicates one valid row has been fetched.


FOR statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

FOR statement

Function

Repeat the execution of a statement list once for each row in a cursor.

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 ]

Usage

Procedures, triggers, and batches only.

Permissions

None.

Side effects

None.

 Description

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.

The name and data type of the local variables that are declared are derived from the statement used in the cursor. With a SELECT statement, the data type will be the data type of the expressions in the select list. The names will be the select list item aliases where they exist; otherwise, they will be the name 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.


FROM clause
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

FROM clause

Function

To specify the database tables or views involved in a SELECT or UPDATE statement.

Syntax

... FROM table-expression, ...

Parameters

table-expression:

  table-spec

| table-expression join-type table-spec [ ON condition ]

| ( table-expression, ... )

table-spec:

[userid . ] table-name [ [AS] correlation-name ]

join-type:

  CROSS JOIN

| [ NATURAL | KEY ] JOIN

| [ NATURAL | KEY ] INNER JOIN

| [ NATURAL | KEY ] LEFT OUTER JOIN

| [ NATURAL | KEY ] RIGHT OUTER JOIN

Usage

Anywhere.

Permissions

Must be connected to the database.

Side effects

None.

 Description

The SELECT and UPDATE statements require a table list to specify which tables will be used by the statement.

Views—Although this description refers to tables, it applies to views unless otherwise noted.

The FROM table list 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.

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 correlation name is used to give a temporary name to the table for this SQL statement only. This is useful when referencing columns which must be qualified by a table name but the table name is long and cumbersome to type. The correlation name is also necessary to distinguish between table instances when referencing the same table more than once in the same query. If no correlation name is specified, then the table name is used as the correlation name for the current 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 only listed 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 is equivalent to

SELECT *

FROM sales_order_items

KEY JOIN sales_order

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.

 Joining tables

 Cross joins

 Generated join conditions

 Natural joins

 Key joins

 INNER JOIN and OUTER JOIN

 Join conditions

 Join abbreviations


Joining tables
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

FROM clause

Joining tables

A JOIN reduces the result set based on the join type and join condition. The join types are described below and the join condition is specified after the keyword ON.

Parentheses can also be used to join one table to more than one other table. For example:

A JOIN (B,C)

joins table A to both tables B and C.

Table expressions can be arbitrarily complex. For example,

A JOIN B JOIN C

A JOIN ( B, C JOIN D )

are legal and meaningful table list expressions. (Any of the valid join types could have been used in the above examples.)


Cross joins
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

FROM clause

Cross joins

A CROSS JOIN does not restrict the results of the join. The query

SELECT *

FROM table1

CROSS JOIN table2

has a result set as follows:

♦	As long as table1 is not the same name as table2:

♦	The columns of the result set includes all columns in table1 and also all columns in table2.

♦	There is one row in the result set for each combination of a row in table1 and a row in table2. If table1 has n1 rows and table2 has n2 rows, the query returns n1 * n2 rows.

♦	If table1 is the same table as table2, and neither is given a correlation name, the result set is simply the rows of table1.


Generated join conditions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

FROM clause

Generated join conditions

Natural joins and key joins are generated join conditions: that is, the keyword KEY or NATURAL indicates a restriction on the join results.

For a natural join, the generated join condition is based on the names of columns in the tables being joined; for a key join, the condition is based on a foreign key relationship between the two tables.


Natural joins
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

FROM clause

Natural joins

A NATURAL JOIN restricts the results by comparing the values of columns in the two tables with the same column name. An error is reported if there are no common column names. A join condition can optionally be specified which further restricts the results of the join.

Column names such as Description or Address often cause a NATURAL JOIN to return different results than expected.


Key joins
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

FROM clause

Key joins

A KEY JOIN restricts the result set based on a foreign key relationship between the two tables. A join condition can optionally be specified which further restricts the results of the join. A key join is valid if exactly one foreign key is identified between the two tables; otherwise, an error indicating the ambiguity is reported.

Parentheses can also be used to join one table to more than one other table. For example

A KEY JOIN (B,C)

joins table A to both tables B and C.

A join involving parentheses is valid if there is an unambiguous join for each table listed in the parentheses.

A KEY JOIN with a view is valid if there is a valid KEY JOIN with exactly one of the tables in the FROM table list of the view definition.

There are two conditions where the meaning of a KEY JOIN is ambiguous. In the first condition, there are two tables A and B where A has a foreign key for B and B has a foreign key for A. The second condition occurs when a table A has two foreign keys for a table B. In either case, the primary table must have a correlation name which is the same as the role name of the foreign key. Otherwise an error will be reported. For example, every SQL Anywhere database has a table called SYSTABLEPERM to hold permission information. Every row in the permission table has two foreign keys for the table describing user IDs (SYSUSERPERM). One foreign key is for the user ID giving the permission (role name grantor) and the other is the user ID getting the permission (role name grantee). A KEY JOIN for the grantor would look like the following:

SYSUSERPERM grantor

KEY JOIN SYSTABLEPERM

and a KEY JOIN for both would look like:

SYSUSERPERM grantor

KEY JOIN SYSTABLEPERM

KEY JOIN SYSUSERPERM grantee


INNER JOIN and OUTER JOIN
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

FROM clause

INNER JOIN and OUTER JOIN

All joins described thus far have been INNER JOINs, which is the default. Each row of

customer INNER JOIN sales_order

contains the information from one customer row and one sales_order row. If a particular customer has placed no orders, there will be no information for that customer.

A LEFT OUTER JOIN B

includes all rows of table A whether or not there is a row in B that satisfies the join condition. If a particular row in A has no matching row in B, the columns in the join corresponding to table B will contain the NULL value. Similarly,

A RIGHT OUTER JOIN B

includes all rows of table B whether or not there is a row in A that satisfies the join condition.


Join conditions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

FROM clause

Join conditions

A join condition can be specified for any join type except CROSS JOIN. The simplest form of join condition is to use it instead of using a KEY or NATURAL join. In the sample database, the following are equivalent:

SELECT *

FROM sales_order

JOIN customer

ON sales_order.cust_id = customer.id

SELECT *

FROM sales_order

KEY JOIN customer

The following two are also equivalent:

SELECT *

FROM department

JOIN employee

ON department.dept_id = employee.dept_id

SELECT *

FROM department

NATURAL JOIN employee

With INNER joins, specifying a join condition is equivalent to adding the join condition to the WHERE clause. However, this is not true for OUTER joins.

A join condition on an OUTER join is part of the join operation. For example, the statement:

SELECT *

FROM employee

KEY LEFT OUTER JOIN Skill

ON skill_name = 'COBOL'

produces a table containing all employees whether or not they have the skill COBOL. Those who do not have the skill COBOL will have the NULL value in the Skill columns. On the other hand, the query:

SELECT *

FROM employee

KEY LEFT OUTER JOIN Skill

WHERE skill_name = 'COBOL'

can be thought of as two separate stages.

♦	The first stage creates the table specified by the FROM clause: SELECT * FROM employee KEY LEFT OUTER JOIN Skill which has at least one row for each employee. Employees who do not have the skill COBOL will have the NULL value in the Skill table columns. For all other employees, there will be one row for each of their skills.

♦	The second stage takes this result and applies the condition:

WHERE skill_name = 'COBOL'

which removes employees without any skills (since the condition is UNKNOWN), and only keeps the skill COBOL for the other employees. Thus, the result has no rows with the NULL value in the Skill columns, so it is clearly different from the result achieved using the join condition.

OUTER joins with join conditions can be complicated. If you are having problems using a join condition, try removing the WHERE clause from the statement to verify that the join is retrieving the rows you expected.


Join abbreviations
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

FROM clause

Join abbreviations

SQL Anywhere provides the following abbreviations for joins.

table1 [INNER | LEFT OUTER | RIGHT OUTER] JOIN table2   If there is no ON join condition specified, the join is assumed to be a KEY join. All key joins are a SQL Anywhere extension. Note that KEY JOIN is not assumed if a join condition is specified.

table1 JOIN table2 ON join-condition   The default join type is an INNER JOIN.


GET DATA statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

GET DATA statement

Function

To get string or binary data for one column on the current row of a cursor. GET DATA is usually used to fetch LONG BINARY or LONG VARCHAR fields. See "SET statement" for putting long values into the database.

Syntax

GET DATA cursor-name COLUMN column-num OFFSET start-offset

...   [ WITH TEXTPTR ]

...     USING DESCRIPTOR sqlda-name

   | INTO host-variable [, ... ]    |

Parameters

cursor-name:   identifier, or host-variable

column-num:   integer or host-variable

start-offset:   integer or host-variable

sqlda-name:   identifier

Usage

Embedded SQL.

Permissions

The cursor must be opened and positioned on a row using FETCH.

Side effects

None.

 Description

Get a piece of one column value from the row at the current cursor position. The value of column-num starts at one and identifies which column's data is to be fetched. That column must be of a string or binary type.

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, and 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.

If the WITH TEXTPTR clause is given, a text pointer is retrieved into a second indicator 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 total length of the data is returned in the SQLCOUNT field of the SQLCA structure.


GET DESCRIPTOR statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

GET DESCRIPTOR statement

Function

Retrieves information about variables within a descriptor area, or retrieves actual data from a variable in a descriptor area

Syntax

GET  DESCRIPTOR descriptor-name

...{ hostvar = COUNT } | VALUE n   assignment [,...] }

Parameters

assignment:

  hostvar = { TYPE | LENGTH | PRECISION | SCALE | DATA | INDICATOR | NAME | NULLABLE | RETURNED_LENGTH }

Usage

Embedded SQL.

Permissions

None.

Side effects

None.

 Description

The Get descriptor statement is used to retrieve information about variables within a descriptor area, or to retrieve actual data from a variable in a descriptor area.

The value n 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.

If an error occurs, it is returned in the SQLCA.


GET OPTION statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

GET OPTION statement

Function

To find the current setting of an option.

Syntax

GET OPTION [ userid. ] option-name

...   | INTO host-variable

   | USING DESCRIPTOR sqlda-name

Parameters

userid:      identifier, string or host-variable

sqlda-name:   identifier

option-name:   identifier, string or host-variable

host-variable:   indicator variable allowed

Usage

Embedded SQL.

Permissions

Must have DBA authority to get someone else's option settings.

Side effects

None.

 Description

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.


GRANT statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

GRANT statement

Function

To give permissions to specific users and to create new user IDs.

Syntax

Syntax 1:

GRANT CONNECT TO userid,... IDENTIFIED BY password,...

Syntax 2:

GRANT

  DBA

| RESOURCE

| GROUP

| MEMBERSHIP IN GROUP userid,...

... TO userid,...

Syntax 3:

GRANT

[

  ALTER

| DELETE

| INSERT

| REFERENCES [ ( column-name,... ) ]

| SELECT [ ( column-name,... ) ]

| UPDATE [ ( column-name,... ) ]

| ALL [ PRIVILEGES ]

], ...

... ON [ owner.]table-name TO userid, ... [ WITH GRANT OPTION ]

Syntax 4:

GRANT EXECUTE ON [ owner.]procedure-name TO userid,...

Usage

Anywhere.

Permissions

For Syntax 1 or 2, must:

♦	Be changing your own password using GRANT CONNECT

♦	Be adding members to your own user ID, or

♦	Have DBA authority.

If changing another user's password, the other user must not be connected to the database.

For Syntax 3, must have one of the following:

♦	Created the table

♦	Been granted permissions on the table with GRANT OPTION

♦	DBA authority

For Syntax 4, must have one of the following:

♦	Created the procedure

♦	DBA authority

Side effects

Automatic commit.

 Description

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.

Syntax 1 and 2 of the GRANT statement are used for granting special privileges to users as follows:

CONNECT   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 when creating groups when you do not want anyone to connect to the group user ID. The password must be a valid identifier, as described in "Watcom-SQL language elements".

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.

RESOURCE   Allows the user to create tables and views.

GROUP   Allows the user(s) to have members. See "Managing groups" for a complete description.

MEMBERSHIP IN GROUP userid,...    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. See "Managing groups" for a complete description.

Syntax 3 of the GRANT statement is used to grant permission on individual tables or views. The table permissions can be listed together, or specifying ALL grants all six permissions at once. The permissions have the following meaning:

ALTER   The users will be allowed to alter this table with the ALTER TABLE statement. This permission is not allowed for views.

DELETE   The users will be allowed to delete rows from this 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 tables, and foreign keys which reference the named tables. If column names are specified, then the users will be allowed to reference only those columns. REFERENCES permissions on columns cannot be granted for views, only for tables.

SELECT [(column-name,...)]   The users will be allowed to look at information in this view or table. If column names are specified, then 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, then the users will be allowed to update only those columns. UPDATE permissions on columns cannot be granted for views, only for tables.

ALL   All of the above permissions.

With Release 5.0.02, there is a change in permission requirements for statements that require reading of a column value.  A statement such as

UPDATE table_name

SET col_name = col_name + 1

or

UPDATE table_name

SET col_name = 1

WHERE col_name = 2

both require that information in the column be read, and so require both UPDATE and SELECT permissions on the column col_name. Prior to release 5.0.02, only UPDATE permissions were required to carry out operations of this sort.

If WITH GRANT OPTION is specified, then the named user ID is also given permission to GRANT the same permissions to other user IDs.

Format 4 of the GRANT statement is used to grant permission to execute a procedure.


GRANT CONSOLIDATE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

GRANT CONSOLIDATE statement

Function

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' ]

Parameters

message-system:

 MAP | FILE | VIM | SMTP

Usage

Anywhere. This statement is applicable only to SQL Remote.

Permissions

Must have DBA authority.

Side effects

Automatic commit.

 Description

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 currently supported message systems are MAPI and FILE. The VIM system is expected to be in beta by the time of release. 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 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 aready 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.


GRANT PUBLISH statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

GRANT PUBLISH statement

Function

To identify the publisher of the current database.

Syntax

GRANT PUBLISH TO userid

Usage

Anywhere. This statement is applicable only to SQL Remote.

Permissions

Must have DBA authority.

Side effects

Automatic commit.

 Description

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.


GRANT REMOTE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

GRANT REMOTE statement

Function

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 } 'hh:mm' ]

Parameters

message-system:

 MAP | FILE | VIM | SMTP

Usage

Anywhere. This statement is applicable only to SQL Remote.

Permissions

Must have DBA authority.

Side effects

Automatic commit.

 Description

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 currently supported message systems are MAPI and FILE. The VIM message system is expected to be in beta at the time of release. 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.


HELP statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

HELP statement

Function

To receive help in the ISQL environment.

Syntax

HELP [topic]

Usage

ISQL.

Permissions

None.

Side effects

None.

Description

The HELP statement is used to enter the ISQL interactive help facility. The topic for help can be optionally specified. If topic is not specified, then the help system is entered at the index.


IF statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

IF statement

Function

Provide conditional execution of SQL statements.

Syntax

IF search-condition THEN statement-list

...   [ ELSEIF search-condition THEN statement-list ] ...

...   [ ELSE statement-list ]

...   END IF

Usage

Procedures, triggers, and batches.

Permissions

None.

Side effects

None.

 Description

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.


INCLUDE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

INCLUDE statement

Function

Include a file into a source program to be scanned by the SQL source language preprocessor.

Syntax

INCLUDE filename

Parameters

filename:   identifier

Usage

Embedded SQL.

Permissions

None.

Side effects

None.

Description

The INCLUDE statement is very much like the C preprocessor #include directive. However, the SQL preprocessor will read the given file inserting its contents into the output C file. Thus, if an include file contains information that the SQL preprocessor requires, it should be included with the Embedded SQL INCLUDE statement.

Two file names are specially recognized: SQLCA and SQLDA. Any C program using Embedded SQL must contain an

EXEC SQL INCLUDE SQLCA;

statement before any Embedded SQL statements. 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 SQLDA's are used.


INPUT statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

INPUT statement

Function

To import data into a database table from an external file or from the keyboard.

Syntax

INPUT INTO [ owner.]table-name

... [ FROM filename | PROMPT ]

... [ FORMAT input-format ]

... [ ESCAPE CHARACTER character ]

... [ BY ORDER | BY NAME ]

... [ DELIMITED BY string ]

... [ COLUMN WIDTHS (integer,...) ]

... [ NOSTRIP ]

... [ ( column-name, ... ) ]

Usage

ISQL.

Permissions

Must have INSERT permission on the table or view.

Side effects

None.

 Description

The INPUT statement allows efficient mass insertion into a 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 containing the input statement—this can even be directly from the ISQL editor. In this case, input is ended with a line containing only the string END.

These lines are inserted into the named table. If a column list is specified, the data is inserted into the specified columns of the named table.

Normally, 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). ISQL will print a warning in the statistics window if any string values are truncated on INPUT. Missing values for NOT NULL columns will be set to zero for numeric types and to the empty string for non-numeric types.

The default escape character for characters stored as hexadecimal codes and symbols is a backslash (\), so that \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.

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 listed below: DBASEII, DBASEIII, DIF, FOXPRO, LOTUS, and WATFILE.

The DELIMITED BY clause allows you to specify a string to be used as the delimiter in ASCII input format.

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, then the widths are determined by the database column types.

Normally, for ASCII input format, trailing blanks will be stripped from quoted 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.

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, inserts a zero in numeric columns and an empty string in character columns.

Each set of values must occupy one input line and must be in the format specified by the FORMAT clause or the format set by the SET INPUT_FORMAT statement if the format clause is not specified. When input is entered by the user, an empty screen 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, DIF, FOXPRO, LOTUS, and WATFILE.

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 , and the sequence .xDD represents the character with hexadecimal code DD.

DBASE   The file is in dBASE II or dBASE III format. ISQL will attempt to determine which of the two DBase formats the file is 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.

DIF   Input file is in Data Interchange Format. 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, then 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 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.

WATFILE   The input will be a WATFILE file. If the table doesn't exist, it will be created.

Input from a command file is terminated by a line containing END. Input from a file is terminated at the end of the file.


INSERT statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

INSERT statement

Function

To insert a single row (format 1) or a selection of rows from elsewhere in the database (format 2) into a table.

Syntax

Format 1

INSERT INTO [ owner.]table-name [( column-name, ... )]

... VALUES ( expression | DEFAULT, ... )

Format 2

INSERT INTO [ owner.]table-name [( column-name, ... )]

... select-statement

Usage

Anywhere.

Permissions

Must have INSERT permission on the table.

Side effects

None.

 Description

The INSERT statement is used to add new rows to a database table.

Format 1 allows the insertion of 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.)

Format 2 allows the user to do 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. The columns from the select list are matched ordinally with the columns specified in the column list or the columns in the order they were created.

Note—The NUMBER(*) function is useful for generating primary keys with format 2 of the INSERT statement (see "Watcom-SQL Functions").

Inserts can be done into 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.

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 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.

Performance hint—To insert many rows into a table, it is more efficient to declare a cursor and use the PUT statement to insert the rows, where possible, than to carry out many separate INSERT statements.


LEAVE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

LEAVE statement

Function

Continue execution by leaving a compound statement or LOOP.

Syntax

LEAVE statement-label

Usage

Procedures, triggers, and batches.

Permissions

None.

Side effects

None.

 Description

The LEAVE statement is a control statement that allows you to leave a labeled compound statement or a labelled loop. Execution resumes at the first statement after the compound statement or loop.

The compound statement that is the body of a procedure or triggers has an implicit label that is the same as the name of the procedure or trigger.


LOAD TABLE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

LOAD TABLE statement

Function

To import data into a database table from an external ascii-format file.

Syntax

LOAD [ INTO ] TABLE [ owner ].table-name

... FROM 'filename-string'

... [ FORMAT 'ascii' ]

... [ DELIMITED BY string ]

... [ STRIP { ON | OFF } ]

... [ QUOTES { ON | OFF } ]

... [ ESCAPES { ON | OFF } ]

... [ ESCAPE CHARACTER character ]

Usage

Anywhere.

Permissions

Must be the creator of the table or have DBA authority. Requires an exclusive lock on the table.

Side effects

Triggers, including referential integrity actions, are not fired by the LOAD TABLE statement. A COMMIT is performed at the end of the load.

 Description

The LOAD TABLE statement allows efficient mass insertion into a database table from an ASCII file. LOAD TABLE is more efficient than the ISQL statement INPUT and can be called from any client application.

LOAD TABLE places an exclusive lock on the whole table; it does not fire any triggers associated with the table.

You can use LOAD TABLE on a temporary table, but the temporary table must have been declared with the ON COMMIT PRESERVE ROWS clause, as 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, inserts a zero in numeric columns and an empty string in character columns.

The following list describes each of the clauses of the statement.

Filename-string   The filename-string is passed to the engine 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. Therefore, 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 pathname is relative to the database engine, not to the client application. If you are running the statement on a database server on some other computer, the directory names refers 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 for Workgroups, 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'

FORMAT option   The only file format currently supported is ASCII. Input lines are assumed to be ASCII characters, one row per line, with values separated by the column delimiter character.

DELIMITED BY option   The default column delimiter character is a comma. You can specify an alternative column delimiter by providing a string. Only the first ASCII character of the string is read. The same formatting requirements apply as to other SQL strings. In particular, 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' ...

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.

QUOTES option   With QUOTES turned on (the default), the LOAD statement looks for a quote character. The quote character is either an apostrophe (single quote) or a quotation mark (double quote). The first such character encountered in the input file is treated as the quote character for the input file.

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',''''

ESCAPES option   With ESCAPES turned on (the default), characters following the backslash character are recognized and interpreted as special characters by the database engine. 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.

ESCAPE CHARACTER option   The default escape character for characters stored as hexadecimal codes and symbols is a backslash (\), so that \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.


LOOP statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

LOOP statement

Function

Repeat the execution of a statement list.

Syntax

 [ statement-label : ]

...[ WHILE search-condition ] LOOP

   ... statement-list

...END LOOP [ statement-label ]

Usage

Procedures, triggers, and batches.

Permissions

None.

Side effects

None.

 Description

The WHILE and LOOP statements are control statements that allow you to repeatedly execute a list of SQL statements 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.


MESSAGE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

MESSAGE statement

Function

To display a message on the message window of the database engine or server.

Syntax

MESSAGE expression

Usage

Procedures, triggers, and batches.

Permissions

Must be connected to the database.

Side effects

None.

 Description

The MESSAGE statement displays an expression on the message window of the database engine or server (not on the client window). It is used primarily for debugging of procedures and triggers.


NULL value
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

NULL value

Function

To specify a value that is unknown or not applicable.

Syntax

NULL

Usage

Anywhere.

Permissions

Must be connected to the database.

Side effects

None.

 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. Note that these 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 the NULL value.

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 also 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 the NULL value.

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 = 1000 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.

The NULL value also has an interesting property when used in numeric expressions. The result of any numeric expression involving the NULL value is the NULL value. This means that if the NULL value is added to a number, the result is the NULL value—not a number. If you want the NULL value to be treated as 0, you must use the ISNULL( expression, 0 ) function (see "Watcom-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.


OPEN statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

OPEN statement

Function

To open a previously declared cursor to access information from the database.

Syntax

OPEN cursor-name

... [   |USING DESCRIPTOR sqlda-name| ]

   | USING host-variable, ...   |

... [ WITH HOLD ]

... [ ISOLATION LEVEL n ]

... [ BLOCK n ]

Parameters

cursor-name:   identifier, or host-variable

sqlda-name:   identifier

Usage

Embedded SQL, procedures, triggers, and batches.

The USING DESCRIPTOR sqlda-name, host-variable and BLOCK n formats are for Embedded SQL only.

Permissions

Must have SELECT permission on all tables in a SELECT statement or EXECUTE permission on the procedure in a CALL statement.

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.

Side effects

None.

 Description

The OPEN statement opens the named cursor. The cursor must be previously declared.

By default, all cursors are automatically closed at the end of the current transaction (COMMIT or ROLLBACK executed). The optional WITH HOLD clause will keep 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.

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 "Cursors in Embedded SQL" or "Using cursors in procedures and triggers").

Embedded SQL

If the cursor name is specified by an identifier or string, then the corresponding DECLARE CURSOR statement must appear prior to the OPEN in the C program; if the cursor name is specified by a host variable, then the DECLARE cursor statement must execute before the OPEN statement.

The optional USING clause specifies the host variables that will be bound to the place-holder bind variables in the SELECT statement for which the cursor has been declared.

The multiuser support fetches rows in blocks (more than 1 at a time). By default, the number of rows in a block is determined dynamically based on the size of the rows and how long it takes the database engine to fetch each row. The application can specify a maximum number of rows that should be contained in a block by specifying the BLOCK clause. For example, if you are fetching and displaying 5 rows at a time, use BLOCK 5. Specifying BLOCK 0 will cause 1 record at a time to be fetched and also cause a FETCH RELATIVE 0 to always fetch the row again.

After successful execution of the OPEN 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. Also, the sqlerrd[2] field of the SQLCA (SQLCOUNT) will be 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 will be the actual number of rows if the database engine can compute it without counting the rows. The database can also be configured to always return the actual number of rows (see the ROW_COUNTS option in SET OPTION statement.), but this can be expensive.


OUTPUT statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

OUTPUT statement

Function

To output the current query results to a file.

Syntax

OUTPUT TO filename

... [ FORMAT output_format ]

... [ ESCAPE CHARACTER character ]

... [ DELIMITED BY string ]

... [ QUOTE string [ ALL ] ]

... [ COLUMN WIDTHS (integer,...) ]

Usage

ISQL.

Permissions

None.

Side effects

The current query results that are displayed in the ISQL data window are repositioned to the top.

 Description

The OUTPUT statement copies the information retrieved by the current query to filename. The output format can be specified with the optional format clause. If no format clause is specified, the OUTPUT_FORMAT option setting is used (see "SET OPTION statement").

The current query is the SELECT or INPUT statement which generated the information displayed in the ISQL data window. The OUTPUT statement will report an error if there is no current query.

The default escape character for characters stored as hexadecimal codes and symbols is a backslash (\), so that \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 '!'

The DELIMITED BY and QUOTE clauses are for the ASCII output format only. The delimiter string will be placed between columns (default comma) and the quote string will be placed around string values (default '—single quote). If ALL is specified in the QUOTE clause, then the quote string will be placed around all values, not just strings.

The COLUMN WIDTH clause is used to specify the column widths for the FIXED format output.

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, 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 , 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 with the column definitions at the top of the file. Note that a maximum of 32 columns can be output. Also, note that columns longer than 255 characters will be truncated in the file.

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. Also, note that columns longer than 255 characters will be truncated in the file.

DIF   The output is a file in the standard Data Interchange Format.

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. Also, note that columns longer than 255 characters will be truncated in the file.

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 ISQL can produce.

SQL   The output is an ISQL INPUT statement required to recreate the information in the table.

TEXT   The output is a TEXT format file which prints the results in columns with the column names at the top and vertical lines separating the columns. This format is similar to that used to display  data in the ISQL data window.

WATFILE   The output is a WATFILE format file with the column definitions at the top of the file.


PARAMETERS statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

PARAMETERS statement

Function

To specify parameters to an ISQL command file.

Syntax

PARAMETERS parameter1, parameter2, ...

Usage

ISQL.

Permissions

None.

Side effects

None.

 Description

The PARAMETERS statement specifies how many parameters there are to a command file and also gives names to those parameters 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 fewer than the required number of parameters, ISQL prompts for values of the missing parameters.

See "Command Files".


PASSTHROUGH statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

PASSTHROUGH statement

Function

To start or stop passthrough mode for SQL Remote administration. Forms 1 and 2 start passthrough mode, while form 3 stops passthrough mode.

Syntax

Syntax 1.    PASSTHROUGH [ ONLY ] FOR userid,...

Syntax 2.    PASSTHROUGH [ ONLY ] FOR SUBSCRIPTION

... TO [ ( owner ) ].publication-name [ ( constant ) ]

Syntax 3.    PASSTHROUGH STOP

Usage

Anywhere. This statement is applicable only to SQL Remote.

Permissions

Must have DBA authority.

Side effects

None.

Description

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. The recipients of the passthrough SQL statements are either a list of user IDs (form 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.


PREPARE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

PREPARE statement

Function

To prepare a statement to be executed later or used for a cursor.

Syntax

PREPARE statement-name

   FROM statement

...[ DESCRIBE describe-type INTO [ [ SQL ] DESCRIPTOR ] descriptor ]

...[ WITH EXECUTE ]

Parameters

statement-name:   identifier, or host-variable

statement :   string, or host-variable

describe-type:

{ ALL |  BIND VARIABLES | INPUT | OUTPUT  |  SELECT LIST  }

...[

     LONG NAMES  [ [ OWNER. ]TABLE. ]COLUMN ]

       | WITH VARIABLE RESULT

    ]

Usage

Embedded SQL.

Permissions

None.

Side effects

Any statement previously prepared with the same name is lost.

 Description

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. 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, then 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.

If the DESCRIBE INTO DESCRIPTOR clause 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.

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 DESRIBE INTO DESCRIPTOR and WITH EXECUTE clauses may improve performance, as they cut down on the required client/server communication.

Describing variable result sets

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 engine 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.

Statements that can be prepared

The following is a list of statements that can be PREPARED.

♦	ALTER

♦	CALL

♦	COMMENT ON

♦	CREATE

♦	DELETE

♦	DROP

♦	GRANT

♦	INSERT

♦	REVOKE

♦	SELECT

♦	SET OPTION

♦	UPDATE

♦	VALIDATE TABLE.

Compatibility issue—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.
Drop statement after use—You should make sure that you DROP the statement after use. If you do not, then the memory associated with the statement is not reclaimed.


PREPARE TO COMMIT statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

PREPARE TO COMMIT statement

Function

To check whether a COMMIT can be performed.

Syntax

PREPARE TO COMMIT

Usage

Anywhere.

Permissions

None.

Side effects

None.

 Description

The PREPARE TO COMMIT statement tests whether a COMMIT can be performed successfully. The statement will cause an error if a COMMIT is not possible without violating the integrity of the database.


PUT statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

PUT statement

Function

To insert a row into the table(s) specified by the cursor. See "SET statement" for putting LONG VARCHAR or LONG BINARY values into the database.

Syntax

PUT cursor-name

...   [  USING DESCRIPTOR sqlda-name

   | FROM host-variable-list ]

...   [   INTO DESCRIPTOR into-sqlda-name

   |  INTO into-host-variable-list ]

...    [ ARRAY :nnn ]

Parameters

cursor-name:   identifier, or host-variable

sqlda-name:   identifier

host-variable-list:   may contain indicator variables

Usage

Embedded SQL.

Permissions

Must have INSERT permission.

Side effects

None.

 Description

Inserts a row into the named cursor. Values for the columns are taken from the 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).

If the sqldata pointer in the SQLDA is the null pointer, then 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. If no values are specified for any of the columns of one particular table involved in the cursor, then no row will be inserted into that table.

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.

One table only—Values can be specified for columns of one table only. Inserting into two different tables through a cursor is not supported.

Inserting into a cursor—When inserting into a cursor, the position of the inserted row is unpredictable. If the cursor involves a temporary table, the inserted record will not show up in the current cursor at all.


READ statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

READ statement

Function

To read ISQL statements from a file.

Syntax

READ filename [ parameters ]

Usage

ISQL.

Permissions

None.

Side effects

None.

 Description

The READ statement reads a sequence of ISQL statements from the named file. This file can contain any valid ISQL statement including other READ statements. READ statements can be nested to any depth. To find the command file, ISQL will first search the current directory, then the directories specified in the environment variable SQLPATH, then the directories specified in the environment variable PATH. If the named file has no file extension, ISQL also searchES each directory for the same file name with the extension 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"). ISQL will then substitute 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 which 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, ISQL prompts for values for the missing parameters.


RELEASE SAVEPOINT statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

RELEASE SAVEPOINT statement

Function

Release a savepoint within the current transaction.

Syntax

RELEASE SAVEPOINT [savepoint-name]

Usage

Anywhere.

Permissions

There must have been a corresponding SAVEPOINT within the current transaction.

Side effects

None.

 Description

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.

For a description of savepoints, see "Savepoints within transactions". Releasing a savepoint does not do any type of commit. It simply removes the savepoint from the list of currently active savepoints.


RESIGNAL statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

RESIGNAL statement

Function

Resignal an exception condition.

Syntax

RESIGNAL [ exception-name ]

Usage

Within an exception handler in a procedure or trigger.

Permissions

None.

Side effects

None.

 Description

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 not undone.


RESUME statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

RESUME statement

Function

To resume a procedure following a query.

Syntax

Syntax 1.

RESUME cursor-name

Syntax 2.

RESUME [ ALL ]

Parameters

cursor-name:   identifier, or host-variable

Usage

Syntax 1: Embedded SQL, procedures, triggers, and batches.

Syntax 1 using a host-variable is for Embedded SQL only.

Syntax 2: ISQL.

Permissions

The cursor must have been previously opened.

Side effects

None.

 Description

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.

The ISQL RESUME statement (Format 2) resumes the current procedure. If ALL is not specified, executing RESUME displays the next result set or, if no more result sets are returned, completes the procedure.

The ISQL RESUME ALL statement cycles through all result sets in a procedure, without displaying them, and completes the procedure. This is useful mainly in testing procedures.


RETURN statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

RETURN statement

Function

To exit from a function or procedure unconditionally, optionally providing a return value. Statements following RETURN are not executed.

Syntax

RETURN [ ( expression ) ]

Usage

Procedures, triggers, and batches

Permissions

None.

Side effects

None.

 Description

A RETURN statement causes an immediate exit from the function or procedure. If expression is supplied, the value of expression is returned as the value of the function or procedure.

Within a function, the expression should be of the same data type as the function's RETURNS data type.

RETURN for procedures is for use with Transact-SQL-compatible procedures. For information, see "Transact-SQL Procedure Language".


REVOKE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

REVOKE statement

Function

To remove permissions for specified user(s).

Syntax

Syntax 1

REVOKE

{     CONNECT

   | DBA

   | RESOURCE

   | GROUP

   | MEMBERSHIP IN GROUP userid,...

}

... FROM userid,...

Syntax 2

REVOKE

{     ALTER

   | DELETE

   | INSERT

   | REFERENCE ,...

   | SELECT

   | UPDATE [(column-name,...)]

   | ALL [PRIVILEGES]

}

... ON [ owner.]table-name FROM userid,...

Syntax 3

REVOKE EXECUTE ON [ owner.]procedure-name FROM userid,...

Usage

Anywhere.

Permissions

Must be the grantor of the permissions that are being revoked or must have DBA authority.

If revoking CONNECT permissions or revoking table permissions from another user, the other user must not be connected to the database.

Side effects

Automatic commit.

 Description

The REVOKE statement is used to remove permissions that were given using the GRANT statement. Form 1 is used to revoke special user permissions and Form 2 is used to revoke table permissions. Form 3 is used to revoke permission to execute a procedure. REVOKE CONNECT is used to remove a user ID from a database. REVOKE GROUP will automatically REVOKE MEMBERSHIP from all members of the group.


REVOKE CONSOLIDATE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

REVOKE CONSOLIDATE statement

Function

To stop a consolidated database from receiving SQL Remote messages from this database.

Syntax

REVOKE CONSOLIDATE FROM userid,...

Usage

Anywhere. This statement is applicable only to SQL Remote.

Permissions

Must have DBA authority.

Side effects

Automatic commit. Drops all subscriptions for the user.

 Description

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.


REVOKE PUBLISH statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

REVOKE PUBLISH statement

Function

To terminate the identification of the named user ID as the CURRENT publisher.

Syntax

REVOKE PUBLISH FROM userid

Usage

Anywhere. This statement is applicable only to SQL Remote.

Permissions

Must have DBA authority.

Side effects

Automatic commit.

 Description

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.  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.


REVOKE REMOTE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

REVOKE REMOTE statement

Function

To stop a user from being able to receive SQL Remote messages from this database.

Syntax

REVOKE REMOTE FROM userid,...

Usage

Anywhere. This statement is applicable only to SQL Remote.

Permissions

Must have DBA authority.

Side effects

Automatic commit. Drops all subscriptions for the user.

Description

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.


ROLLBACK statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

ROLLBACK statement

Function

To undo any changes made since the last commit or rollback.

Syntax

ROLLBACK [ WORK ]

Usage

Anywhere.

Permissions

Must be connected to the database.

Side effects

Closes all cursors not opened WITH HOLD.

 Description

The ROLLBACK statement ends a logical unit of work (transaction) and undoes all changes made to the database during this transaction. A transaction is the database work done between COMMIT or ROLLBACK statements on one database connection.


ROLLBACK TO SAVEPOINT statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

ROLLBACK TO SAVEPOINT statement

Function

To cancel any changes made since a SAVEPOINT.

Syntax

ROLLBACK TO SAVEPOINT [savepoint-name]

Usage

Anywhere.

Permissions

There must have been a corresponding SAVEPOINT within the current transaction.

Side effects

None.

 Description

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. For a description of savepoints, see "Savepoints within transactions".

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.


ROLLBACK TRIGGER statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

ROLLBACK TRIGGER statement

Function

To undo any changes made in a trigger.

Syntax

ROLLBACK TRIGGER [ WITH raiserror-statement ]

Usage

In a trigger

Permissions

Must be connected to the database.

Side effects

None

 Description

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.


SAVEPOINT statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

SAVEPOINT statement

Function

To establish a savepoint within the current transaction.

Syntax

SAVEPOINT [savepoint-name]

Usage

Anywhere.

Permissions

None.

Side effects

None.

 Description

Establish a savepoint within the current transaction. The savepoint-name is an identifier that can be used in an 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 is executing or while an atomic compound statement is executing are automatically released when the atomic operation ends.


SELECT statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

SELECT statement

Function

To retrieve information from the database.

Syntax

SELECT [ ALL | DISTINCT ] select-list

...[ INTO { host-variable-list  | variable-list } ]

...[ FROM table-list ]

...[ WHERE search-condition ]

...[ GROUP BY column-name, ... ]

...[ HAVING search-condition ]

...[ ORDER BY { expression | integer } [ ASC | DESC ], ... ]

Parameters

select-list:

    table-name

   | expression [ [ AS ] alias-name ]

   | *

Usage

Anywhere

The INTO clause with host-variable-list is used in Embedded SQL only.

The INTO clause with variable-list is used in procedures and triggers only.

Permissions

Must have SELECT permission on the named tables and views.

Side effects

None.

 Description

The SELECT statement is used for retrieving results from the database.

A SELECT statement can be used in ISQL 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. The various parts of the SELECT statement are described below:

ALL or DISTINCT   If neither ALL nor DISTINCT is specified, ALL rows which satisfy the clauses of the SELECT statement are retrieved. If DISTINCT is specified, duplicate output rows are eliminated. This is called the projection of the result of the statement. In many cases, statements take significantly longer to execute when DISTINCT is specified. Thus, the use of DISTINCT should be reserved for cases where it is necessary.

If DISTINCT is used, the statement cannot contain an aggregate function with a DISTINCT parameter.

select list   The select list is a list of expressions separated by commas specifying what will be retrieved from the database. If asterisk (*) is specified, it is expanded to select all columns of all tables in the FROM clause (table-name all columns of the named table). Aggregate functions are allowed in the select list (see "Watcom-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 ISQL at the top of each column of output from the SELECT statement. If the optional alias name is not specified after an expression, ISQL will display the expression.

INTO host-variable-list   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.

FROM table-list   Rows are retrieved from the tables and views specified in the table list. Joins can be specified using join operators. For more information, see "FROM clause". 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

WHERE search-condition   that will be selected from the tables named in the FROM clause. It is also used to do joins between multiple tables. This is accomplished by putting a condition in the WHERE clause that relates a column or group of columns from one table with a column or group of columns from another table. Both tables must be listed in the FROM clause.

See "Search conditions" for a full description.

GROUP BY { column-name | alias | function }, ...    database. You can group by columns or alias names or functions. GROUP BY expressions must also appear in the select list. The result of the query contains one row for each distinct set of values in the named columns, aliases, or functions. 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. For the sake of GROUP BY, all NULL values are treated as identical. 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 cannot reference any identifiers except those named in the GROUP BY clause. The exception is that the select list and HAVING clause may contain aggregate functions.

HAVING search-condition   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 if 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 expression, ...    results of a query. Each item in the ORDER BY list can be labeled as ASC for ascending order or DESC for descending order. Ascending is assumed if neither is specified. If the expression is an integer N, then the query results will be sorted by the N'th item in the select list.

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.


SET statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

SET statement

Function

To assign a value to a SQL variable.

Syntax

SET identifier = expression

Usage

Anywhere.

Permissions

None.

Side effects

None.

 Description

The SET statement assigns a new value to a variable that was previously created using the CREATE VARIABLE statement.

A variable can be used in a SQL statement anywhere a column name is allowed. If there is no column name that matches the identifier, the database engine checks to see if there is a variable that matches and uses its value.

Variables are local to the current connection, and disappear when you disconnect from the database or when you 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.


SET CONNECTION statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

SET CONNECTION statement

Function

To change the active database connection.

Syntax

SET CONNECTION [connection-name]

Parameters

connection-name:

   identifier, string or host-variable

Usage

ISQL.

Permissions

None.

Side effects

None.

 Description

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.

Cursors and connections—When cursors are opened in Embedded SQL, they are associated with the current connection. When the connection is changed, the cursor names will not be accessible. The cursors remain active and in position and will become accessible when the associated connection becomes active again.


SET DESCRIPTOR statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

SET DESCRIPTOR statement

Function

Describes the variables in a SQL descriptor area, and places data into the descriptor area.

Syntax

SET  DESCRIPTOR descriptor-name

...{ COUNT = {  integer | hostvar } | VALUE n   assignment [,...] }

Parameters

assignment:

  { TYPE | SCALE | PRECISION | LENGTH | INDICATOR  }

   ... =  { integer | hostvar }

| DATA = hostvar

Usage

Embedded SQL.

Permissions

None.

Side effects

None.

 Description

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 n 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.

If an error occurs, the code is returned in the SQLCA.


SET OPTION statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

SET OPTION statement

Function

To change ISQL and database options.

Syntax

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

Note: Syntax 2 and 3 are for ISQL options only.

Usage

All (Syntax 1), ISQL (all syntaxes).

Permissions

None required to set your own options. Must have DBA authority to set database options for another user or PUBLIC.

Side effects

If TEMPORARY is not specified, an automatic commit is performed.

 The classes of options are:

♦	General database options

♦	Transact-SQL compatibility database options

♦	Replication database options

♦	ISQL options

Description

The SET statement is used to change options for both the database and the ISQL environment. The userid parameter can be specified to change someone else's options, however, you must have DBA authority to do so. Specifying TEMPORARY will change the option setting for the current connection only. In this case, userid cannot be specified.

Also, in Embedded SQL, only database options can be set temporarily.

Changing a PUBLIC option sets the option value for any userid which has not SET their own value for that option. An option cannot be set for a user ID other than PUBLIC unless there is already a PUBLIC setting for that option. Only a user with DBA authority is allowed to set options for another user ID (including PUBLIC).

If option-value is omitted, the specified option setting will be deleted from the database. If it was a personal option setting, then the value used will revert back to the PUBLIC setting. If a TEMPORARY option is deleted, the option setting will revert back to the permanent setting.

Temporary setting—Only your own ISQL and database options can be made TEMPORARY; options for other software and any options set for another user produces an error if TEMPORARY is specified.

SET PERMANENT (syntax 2) stores all current ISQL options in the SYS.SYSOPTIONS table in the database. These settings are automatically established every time ISQL is started for the current user ID.

Syntax 3 is used to display all of the current option settings. If there are temporary options set for ISQL or the database engine, these will be displayed; otherwise, the permanent option settings are displayed.

 Database options

 Compatibility options

 Replication options

 ISQL options


Database options
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

SET OPTION statement

Database options

This section lists all database options with the exception of Transact-SQL compatibility database options and replication database options.

OPTION	VALUES	DEFAULT
BACKGROUND_PRIORITY	ON, OFF	OFF
BLOCKING	ON,OFF	ON
CHECKPOINT_TIME	number of minutes	60
COOPERATIVE_COMMITS	ON,OFF	ON
COOPERATIVE_COMMIT_TIMEOUT	integer	250
DATE_FORMAT	string	'YYYY-MM-DD''MM/DD/YYYY' (1)
DATE_ORDER	'YMD','DMY','MDY'	'YMD'MDY' (1)'
DELAYED_COMMITS	ON,OFF	OFF
DELAYED_COMMIT_TIMEOUT	integer	500
ISOLATION_LEVEL	0,1,2,3	0
PRECISION	number of digits	30
QUERY_PLAN_ON_OPEN	ON,OFF	OFF
QUOTED_IDENTIFIER	ON,OFF	ON
RECOVERY_TIME	number of minutes	2
ROW_COUNTS	ON,OFF	OFF
SCALE	number of digits	6
SQL_FLAGGER_ERROR_LEVEL	E,I,F,W	W
SQL_FLAGGER_WARNING_LEVEL	E,I,F,W	W
THREAD_COUNT	number of threads	0
TIME_FORMAT	string	'HH:NN:ss.SSS'
TIMESTAMP_FORMAT	string	'YYYY-MM-DD HH:NN:ss.SSS'
WAIT_FOR_COMMIT	ON,OFF	OFF
$(1) Default for databases created with Watcom SQL 3.0.

BACKGROUND_PRIORITY

When set to ON, requests on the current connection will 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. The default setting is OFF.

BLOCKING

Controls whether locking conflicts result in one user becoming blocked or an error condition being returned. The default is ON. See "Transaction blocking and deadlock".

CHECKPOINT_TIME

Set the maximum desired length of time that the database engine will run without doing a checkpoint. The time is specified in minutes (the default value set by DBINIT is 60). This option is used with the RECOVERY_TIME option to decide when checkpoints should be done. See "The checkpoint log".

Because this is a global option for the database, only the PUBLIC setting is used. Individual settings for users will have no effect. Also, changing this option does not take effect immediately. You must shut down the database engine and restart for the change to take effect.

COOPERATIVE_COMMITS

If COOPERATIVE_COMMITS is set to OFF, a COMMIT is written to disk as soon as it is received by the database engine, and the application is then allowed to continue.

When COOPERATIVE_COMMITS is set to ON (the default), the database engine does not immediately write the COMMIT to the disk. Instead, it requires the application to wait for a 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 engine 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, then 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.

COOPERATIVE_COMMIT_TIMEOUT

This option only has meaning when COOPERATIVE_COMMITS is set to ON. The COOPERATIVE_COMMIT_TIMEOUT option setting governs when a COMMIT entry in the transaction log is written to disk. With COOPERATIVE_COMMITS set to ON, the database engine waits for the number of milliseconds set in the COOPERATIVE_COMMIT_TIMEOUT option for other connections to fill a page of the log before writing to disk. The default setting is 250 milliseconds.

DATE_FORMAT

Sets the format used for dates retrieved from the database. 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
aa	Am or pm (12 hour clock)
pp	PM if needed (12 hour clock)
f	Use French days and months
Each symbol is substituted with the appropriate data for the date being formatted. Any format symbol that represents character rather than digit output can be put in upper case which will cause the substituted characters to also be in upper case. For numbers, using mixed case in the format string will suppress leading zeros.

Note—The default date format has changed since Watcom SQL 3.0. The new format corresponds to ISO date format specifications ('YYYY-MM-DD'). Databases created with Watcom SQL 3.0 will still use the old option value. In addition, the new default date format does not specify hours and minutes. TIMESTAMP_FORMAT includes hours, minutes and seconds.

DATE_ORDER

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'.

Note—The default date order has changed since Watcom SQL 3.0. The new order ('YMD') corresponds to ISO date format specifications. Databases created with Watcom SQL 3.0 will still use the old option value which was 'MDY'.

DELAYED_COMMITS

When set to ON, the database engine or 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. This option must be set to OFF for ANSI/ISO COMMIT behavior.

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 engine 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, then 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.

DELAYED_COMMIT_TIMEOUT

This option only has meaning when DELAYED_COMMITS is set to ON. With DELAYED_COMMITS set ON, the DELAYED_COMMIT_TIMEOUT option setting governs when a COMMIT entry in the transaction log is written to disk. With DELAYED_COMMITS set to ON, the database engine 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. The default setting is 500 milliseconds.

ISOLATION_LEVEL

Controls the locking isolation level as follows.

♦	0   Allow dirty reads, nonrepeatable reads, and phantom rows.

♦	1   Prevent dirty reads. Allow nonrepeatable 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.

The default is 0. See "Isolation levels and consistency".

PRECISION

Specifies the maximum number of digits in the result of any decimal arithmetic. 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 for overflow.

RECOVERY_TIME

Sets the maximum length of time that the database engine will take to recover from system failure. The time is specified in minutes (the default value set by DBINIT is 2). This option is used with the CHECKPOINT_TIME option to decide when checkpoints should be done. See "Recovery from system failure". SQL Anywhere uses a heuristic to measure the recovery time based on the operations since the last checkpoint. Thus, the recovery time is not exact. Because this is a global option for the database, only the PUBLIC setting is used. Individual settings for users will have no effect. Also, changing this option does not take effect immediately. You must shut down the database engine and restart it for the change to take effect.

ROW_COUNTS

Specifies whether the database will always count the number of rows in a query when it is opened. If this option is off, the row count, the row count is usually only an estimate.  If this option is on, the row count is always accurate but opening queries may take significantly longer.

SCALE

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. See the PRECISION option for an example.

THREAD_COUNT

Sets the number of execution threads that will be used in the database engine while running with multiple users. This number controls the number of concurrent requests that the database engine will process. A value of 0 (the default) means an operating system specific value, which is 8 for DBENG50S and 20 for all other engines and servers.

Because this is a global option for the database, only the PUBLIC setting is used. Individual settings for users will have no effect. Also, changing this option does not take effect immediately. You must shut down the database engine and restart for the change to take effect.

TIME_FORMAT

Sets the format used for times retrieved from the database. 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 will be substituted with the appropriate data for the date being formatted. Any format symbol that represents character rather than digit output can be put in uppercase which will cause the substituted characters to also be in uppercase. For numbers, using mixed case in the format string will suppress leading zeros.

TIMESTAMP_FORMAT

Sets the format used for timestamps retrieved from the database. 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
Each symbol is substituted with the appropriate data for the date being formatted. Any format symbol that represents character rather than digit output can be put in uppercase which will cause the substituted characters to also be in uppercase. For numbers, using mixed case in the format string will suppress leading zeros.

WAIT_FOR_COMMIT

If this option is on, the database will not check foreign key integrity until the next COMMIT statement. Otherwise, all foreign keys not created with the CHECK ON COMMIT option are checked as they are inserted, updated or deleted.


Compatibility options
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

SET OPTION statement

Compatibility options

Compatibility options are database options included to allow SQL Anywhere behavior to be made compatible with SQL Server, or to support both old behavior and allow ISO SQL/92 behavior.

OPTION	VALUES	DEFAULT
ALLOW_NULLS_BY_DEFAULT	ON, OFF	ON
ANSI_BLANKS	ON, OFF	OFF
ANSI_INTEGER_OVERFLOW	ON, OFF	ON
ANSINULL	ON, OFF	ON
ANSI_PERMISSIONS	ON, OFF	ON
AUTOMATIC_TIMESTAMP	ON, OFF	OFF
CHAINED	ON, OFF	ON
CLOSE_ON_ENDTRANS	ON, OFF	OFF
CONVERSION_ERROR	ON,OFF	ON
DIVISION_BY_ZERO_ERROR	ON, OFF	OFF
FIRE_TRIGGERS	ON, OFF	ON
NEAREST_CENTURY	integer	0
NON_KEYWORDS	comma-separated keywords list	No keywords turned off
QUERY_PLAN_ON_OPEN	ON, OFF	OFF
QUOTED_IDENTIFIER	ON, OFF	ON
RI_TRIGGER_TIME	BEFORE, AFTER	AFTER
SQL_FLAGGER_ERROR_LEVEL	E, I, F, W	W
SQL_FLAGGER_WARNING_LEVEL	E, I, F, W	W
STRING_RTRUNCATION	ON, OFF	OFF
TSQL_HEX_CONSTANT	ON, OFF	OFF
TSQL_VARIABLES	ON, OFF	OFF
ALLOW_NULLS_BY_DEFAULT

Controls whether new columns created without specifying either NULL or NOT NULL are allowed contain NULL values. The ALLOW_NULLS_BY_DEFAULT option is included for Transact-SQL compatibility. The default is ON. See "Setting options for Transact-SQL compatibility".

ANSI_BLANKS

The ANSI_BLANKS option has no effect unless the database was created with the -b command-line option. For databases created with the -b command-line option, turning ANSI_BLANKS on 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 the truncated characters include non-blank characters.

If ANSI_BLANKS is ON, then when supplying a value of data type DT_STRING, the :name.sqllen:ename. field must be set 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.

ANSI_INTEGER_OVERFLOW

The ISO SQL/92 standard requires that an arithmetic operation resulting in an integer overflow should result in an error SQLSTATE = 22003 - overflow error.  SQL Anywhere behavior was different from this previously.  The ANSI_INTEGER_OVERFLOW option can be set to OFF to maintain compatibility with previous releases of the software. The default setting is OFF.

ANSINULL

With ANSINULL ON, results of comparisons with NULL using '=' or '!=' are unknown. Also, aggregate functions on columns containing NULL values cause the warning 'null value eliminated in aggregate function' (SQLSTATE=01003). ANSINULL 'off' allows comparisons with NULL to yield results that are not unknown, for compatibility with SQL Server, and turns off the warning. The default setting is ON.

ANSI_PERMISSIONS

With ANSI_PERMISSIONS ON (the default), SQL92 permissions requirements for  delete and update statements are checked. The default value is off in SQL Server. The following table outlines the differences.

SQL Statement	Permissions Required with ansi_permissions off	Permissions Required with ansi_permissions on
UPDATE	update permission on columns where values are being set	update permission on columns where values are being set select permission on all columns appearing in  where clause. SElect permission on all columns on right side of set clause.
DELETE	delete permission on table	delete permission on table. select permission on all columns appearing in  where clause
The ANSI_PERMISSIONS option can be set only for the PUBLIC group. No private settings are allowed.

AUTOMATIC_TIMESTAMP

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. The AUTOMATIC_TIMESTAMP option is included for Transact-SQL compatibility. The default is OFF. See "Setting options for Transact-SQL compatibility".

CHAINED

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.  For SQL Anywhere the default setting is ON; for SQL Server the default setting is OFF.

CLOSE_ON_ENDTRANS

When CLOSE_ON_ENDTRANS is set to ON, cursors are closed at the end of a transaction; when set to OFF cursors are not closed.  This behavior can be overridden by opening a cursor 'WITH HOLD'. The default is OFF, and ON provides Transact-SQL compatible behavior.

CONVERSION_ERROR

Controls whether conversion errors will be reported by the database, or ignored. If conversion errors are ignored, the NULL value is used in place of the value that could not be converted.

DIVISION_BY_ZERO_ERROR

The DIVIDE_BY_ZERO_ERROR option indicates whether division by zero is reported as an error. If the option is set OFF division by zero is not an error - this is the previous behavior. If the option is set ON, then division by zero results in an error with SQLSTATE 22012. The default setting is ON.

FIRE_TRIGGERS

When set to ON (the default), 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 SQL Server to SQL Anywhere, as all actions from SQL Server transaction logs are replicated to SQL Anywhere, including actions carried out by triggers.

NEAREST_CENTURY

Controls handling of two-digit years, when converting from strings to dates or timestamps. The historical SQL Anywhere behavior is to add 1900 to the year. SQL Server behavior is to use the nearest century, so that if the year value yy is less than 50, then the year is set to 20yy.

The NEAREST_CENTURY setting is a numeric value that acts as a roll-over 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 setting is 0, which gives the historical SQL Anywhere behavior.

NON_KEYWORDS

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 you can 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 the options is that SQL statements using a turned off keyword cannot be used: they produce a syntax error.

QUERY_PLAN_ON_OPEN

In previous versions of the product, each time an OPEN was done on a cursor, the engine 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.

QUOTED_IDENTIFIER

Controls whether strings enclosed in double quotes are interpreted as identifiers (ON) or as literal strings (OFF). The QUOTED_IDENTIFIER option is included for Transact-SQL compatibility. The default is ON. See "Setting options for Transact-SQL compatibility".

RI_TRIGGER_TIME

RI_TRIGGER_ACTION controls the relative timing of referential integrity checks and trigger actions. The option can be set to either BEFORE or AFTER. When set to AFTER, RI actions are executed AFTER the update or delete. The default setting is AFTER and only the PUBLIC setting can be used: any other setting is ignored.

Prior to 5.5, the referential integrity  triggers were always fired BEFORE. Starting with Release 5.5, the RI_TRIGGER_TIME option allows RI triggers to be fired before or after, with the default being to fire AFTER.

The reason for the change of default behavior is that BEFORE triggers give possibilities for infinitely recursing triggers when deleting from self-referencing rows.

SQL_FLAGGER_ERROR_LEVEL

This option flags any 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

♦	W   Allow all supported syntax

SQL_FLAGGER_WARNING_LEVEL

This option flags any 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

♦	W   Allow all supported syntax

STRING_RTRUNCATION

Determines whether an error is  raised when an insert or update truncates a char or varchar string. If the truncated characters consist only of spaces, no exception is raised. The setting of ON corresponds to ANSI/ISO SQL/92 behavior. When set to OFF, the exception is not raised and the character string is silently truncated.

TSQL_HEX_CONSTANT

When set to ON, hexadecimal constants are treated as binary typed constants. To get the historical behavior, set the option to OFF. The default setting is ON.

TSQL_VARIABLES

When set to ON, you can use the @ sign instead of the colon a s a prefix for host variable names in Embedded SQL. This is implemented primarily for the Open Server Gateway.


Replication options
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

SET OPTION statement

Replication options

Replication options are database options 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
DELETE_OLD_LOGS	ON,OFF	OFF
REPLICATE_ALL	ON,OFF	OFF
REPLICATION_ERROR	procedure-name	(no procedure)
VERIFY_THRESHOLD	integer	1000
VERIFY_ALL_COLUMNS	ON,OFF	OFF
DELETE_OLD_LOGS

This option is used by SQL Remote and by the SQL 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.

REPLICATE_ALL

This option is used by the SQL Anywhere LTM only. The default setting is OFF. When it is set to ON, the entire database is set to act as a primary site in a Replication Server installation. All changes to the database are sent to Replication Server by the LTM.

REPLICATION_ERROR

For SQL Remote, the REPLICATION_ERROR option allows you to specify a stored procedure 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 eror.

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.

VERIFY_THRESHOLD

This option is used by SQL Remote only. The default setting 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.

VERIFY_ALL_COLUMNS

This option is used by SQL Remote only. 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.


ISQL options
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

SET OPTION statement

ISQL options

OPTION	VALUES	DEFAULT
AUTO_COMMIT	ON,OFF	OFF
AUTO_REFETCH	ON,OFF	ON
BELL	ON,OFF	ON
COMMAND_DELIMITER	string	';'
COMMIT_ON_EXIT	ON,OFF	ON
ECHO	ON,OFF	ON
HEADINGS	ON,OFF	ON
INPUT_FORMAT	ASCII FIXED DIF DBASE DBASEII DBASEIII FOXPRO LOTUS WATFILE	ASCII
ISQL_LOG	file-name	''
NULLS	string	'(NULL)'
ON_ERROR	STOP CONTINUE PROMPT EXIT NOTIFY_CONTINUE NOTIFY_STOP NOTIFY_EXIT	PROMPT
OUTPUT_FORMAT	TEXT ASCII FIXED DIF DBASEII DBASEIII FOXPRO LOTUS SQL WATFILE	ASCII
OUTPUT_LENGTH	integer	0
STATISTICS	0,3,4,5,6	3
TRUNCATION_LENGTH	integer	30
AUTO_COMMIT

If AUTO_COMMIT is on, a database COMMIT is performed after each successful statement and a ROLLBACK after each failed statement. Otherwise, a COMMIT or ROLLBACK is only performed when the user issues a COMMIT or ROLLBACK statement or if the user issues a SQL statement which causes an automatic commit such as the CREATE TABLE statement.

AUTO_REFETCH

If AUTO_REFETCH is on, then the current query results displayed in the Data window 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.

BELL

Controls whether the bell will sound when an error occurs.

COMMAND_DELIMITER

Sets the string indicating the termination of a statement in ISQL. The default setting is a single semicolon ';'. This must be changed in order to create triggers and procedures from ISQL using the CREATE TRIGGER or CREATE PROCEDURE statement. The change prevents the semi-colons terminating individual statements within the trigger or procedure from being interpreted as the termination of the CREATE statement itself.

A common setting for this option is '\'.

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.

COMMIT_ON_EXIT

Controls which of a COMMIT or ROLLBACK is done when leaving ISQL. With COMMIT_ON_EXIT is set to ON (the default), a COMMIT is done; otherwise a ROLLBACK is done.

ECHO

Controls whether statements are echoed before they are executed. This is most useful when using the READ statement to execute an ISQL command file.

HEADINGS

Controls whether headings will be displayed for the results of a SELECT statement.

INPUT_FORMAT

Sets the default data format expected by the INPUT statement.

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, DIF, FOXPRO, LOTUS, and WATFILE.

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 , and the sequence \xDD represents the character with hexadecimal code DD.

DBASE   The file is in dBASE II or dBASE III format. ISQL will attempt to determine which of the two DBase formats the file is 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.

DIF   Input file is in Data Interchange Format. 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, then 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 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.

WATFILE   The input will be a WATFILE file. If the table doesn't exist, it will be created.

ISQL_LOG

If ISQL_LOG is set to a non-empty string, all ISQL statements are added to the end of the named file. Otherwise, if ISQL_LOG is set to the empty string ISQL statements are not logged.

Individual session only—This is logging of an individual ISQL session only. See "Backup and Data Recovery" for a description of the transaction log which logs all changes to the database by all users.

NULLS

Specifies how NULL values in the database will be displayed. The default is (NULL) (including the parentheses).

ON_ERROR

Controls what happens if an error is encountered while reading statements from a command file as follows:

STOP

ISQL will stop reading statements from the file and return to the statement window for input.

PROMPT

ISQL will prompt the user to see if the user wishes to continue.

CONTINUE

The error will be ignored and ISQL will continue reading statements from the command file.  The INPUT statement will continue with the next row, skipping  the row that caused the error.

EXIT

ISQL will terminate.

NOTIFY_CONTINUE

The error is displayed in a message box with a single Continue button. Execution continues once the button is clicked.

NOTIFY_STOP

The error is displayed in a message box with a single Stop button. Execution of the script stops once the button is clicked.

NOTIFY_EXIT

The error is displayed in a message box with a single Exit button. ISQL terminates once the button is clicked.

OUTPUT_FORMAT

Sets the output format for the data retrieved by the SELECT statement and redirected into a file. This is also the default output format for the OUTPUT statement. 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 ,  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 with the column definitions at the top of the file. Note that a maximum of 32 columns can be output. Also, note that columns longer than 255 characters will be truncated in the file.

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. Also, note that columns longer than 255 characters will be truncated in the file.

DIF   The output is a file in the standard Data Interchange Format.

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. Also, note that columns longer than 255 characters will be truncated in the file.

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 ISQL can produce.

SQL   The output is an ISQL INPUT statement required to recreate the information in the table.

TEXT   The output is a TEXT format file which prints the results in columns with the column names at the top and vertical lines separating the columns. This format is similar to that used to display  data in the ISQL data window.

WATFILE   The output is a WATFILE format file with the column definitions at the top of the file.  WATFILE is a tabular file management tool available from Watcom.

OUTPUT_LENGTH

Controls the length used when ISQL exports information to an external file (using output redirection or the OUTPUT statement). The default for Output_length is 0—no truncation.

STATISTICS

Controls whether execution times, optimization strategies and other statistics will be displayed in the statistics window. This option can be set to 0, 3, 4, 5, or 6. When 0, the statistics window is not displayed. Otherwise, the value represents the height of the statistics window in lines.

TRUNCATION_LENGTH

When SELECT statement results are displayed on the screen, each column of output is limited to the width of the screen. The TRUNCATION_LENGTH option is used to reduce the width of wide columns so that more than one column will fit on the screen. A value of 0 means that columns will not be truncated.


SET SQLCA statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

SET SQLCA statement

Function

To tell the SQL preprocessor to use a SQLCA other than the default global sqlca.

Syntax

SET SQLCA sqlca

Parameters

sqlca:   identifier or string

Usage

Embedded SQL.

Permissions

None.

Side effects

None.

 Description

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 only necessary when you are writing code that is reentrant (see "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.


SIGNAL statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

SIGNAL statement

Function

Signal an exception condition.

Syntax

SIGNAL exception-name

Usage

Procedures, triggers, and batches.

Permissions

None.

Side effects

None.

 Description

SIGNAL allows you to raise an exception. See "Using exception handlers in procedures and triggers" for a description of how exceptions are handled.


START DATABASE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

START DATABASE statement

Function

To start a database on the specified database engine

Syntax

START DATABASE database-file

... [ AS database-name ]

... [ ON engine-name ]

... [ AUTOSTOP { YES | NO ]

Usage

ISQL

Permissions

None

Side effects

None

 Description

The START DATABASE statement starts a specified database on a specified database engine. The database engine must be running. The full path must be specified for the database-file unless the file is located in the current directory.

The START DATABASE statement does not connect ISQL to the specified database: a CONNECT statement needs to be issued in order to make a connection.

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:\SQLANY50\SADEMO.DB would be given the default name of sademo.

If engine-name is not specified, the default database engine is assumed. The default database engine is the first started engine among those currently running.

The default setting for the AUTOSTOP clause is YES. With AUTOSTOP set to YES, the database is unloaded when the last connection to it is dropped.  If AUTOSTOP is set to NO, the database is not unloaded.


START ENGINE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

START ENGINE statement

Function

To start a database engine

Syntax

START ENGINE AS engine-name [ STARTLINE command-string ]

Usage

ISQL

Permissions

None

Side effects

None

 Description

The START ENGINE statement starts a database engine. If you wish to specify a set of options for the engine, use the STARTLINE keyword together with a command string. Valid command strings are those that conform to the database engine command-line description in the chapter "SQL Anywhere Components".


START SUBSCRIPTION statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

START SUBSCRIPTION statement

Function

To start a subscription for a user to a publication.

Syntax

START SUBSCRIPTION TO publication-name [ ( string ) ]

...  FOR userid,...

Usage

Anywhere. This statement is applicable only to SQL Remote.

Permissions

Must have DBA authority.

Side effects

Automatic commit.

 Description

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.


STOP DATABASE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

STOP DATABASE statement

Function

To stop a database on the specified database engine

Syntax

STOP DATABASE database-name

...   [ ON engine-name ]

...   [ UNCONDITIONALLY ]

Usage

ISQL

Permissions

None

Side effects

None

 Description

The STOP DATABASE statement stops a specified database on a specified database engine. If engine-name is not specified, all running engines will be searched for a database of the specified name.

If the UNCONDITIONALLY keyword is supplied, the database will be stopped even if there are connections to the database. If UNCONDITIONALLY is not specified, the database will not be stopped if there are connections to it.


STOP ENGINE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

STOP ENGINE statement

Function

To stop a database engine

Syntax

STOP ENGINE engine-name [ UNCONDITIONALLY ]

Usage

ISQL

Permissions

None

Side effects

None

 Description

The STOP ENGINE statement stops the specified database engine. If the UNCONDITIONALLY keyword is supplied, the database engine will be stopped even if there are connections to the engine. If UNCONDITIONALLY is not specified, the database engine will not be stopped if there are connections to it.


STOP SUBSCRIPTION statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

STOP SUBSCRIPTION statement

Function

To stop a subscription for a user to a publication.

Syntax

STOP SUBSCRIPTION TO publication-name [ ( constant ) ]

...    FOR userid,...

Usage

Anywhere. This statement is applicable only to SQL Remote.

Permissions

Must have DBA authority.

Side effects

Automatic commit.

 Description

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.


SYNCHRONIZE SUBSCRIPTION statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

SYNCHRONIZE SUBSCRIPTION statement

Function

To synchronize a subscription for a user to a publication.

Syntax

SYNCHRONIZE SUBSCRIPTION TO publication-name [ ( string ) ]

...    FOR userid,...

Usage

Anywhere. This statement is applicable only to SQL Remote.

Permissions

Must have DBA authority.

Side effects

Automatic commit.

 Description

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.


SYSTEM statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

SYSTEM statement

Function

To execute an operating system command from within ISQL.

Syntax

SYSTEM [ operating-system-command ]

Usage

ISQL (DOS and QNX only).

Permissions

None.

Side effects

None.

 Restrictions

♦	The SYSTEM statement must be entirely contained on one line.

♦	Comments are not allowed at the end of a SYSTEM statement.

Description

Executes the specified operating system command. If no command is specified, the DOS command interpreter or QNX shell is started. You can return to ISQL by using the DOS exit command or by pressing CTRL+D in QNX.


TRUNCATE TABLE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

TRUNCATE TABLE statement

Function

To delete all rows from a table, without deleting the table definition.

Syntax

TRUNCATE TABLE [ owner.]table-name

Usage

Anywhere.

Permissions

Must be the table owner or have DBA authority.

Side effects

Delete triggers are not fired by the TRUNCATE TABLE statement.

 Description

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.


UNION operation
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

UNION operation

Function

To combine the results of two or more select statements.

Syntax

select-without-order-by

...   UNION [ALL] select-without-order-by

... [ UNION [ALL] select-without-order-by ] ...

... [ ORDER BY integer [ ASC | DESC ], ... ]

Usage

Anywhere.

Permissions

Must have SELECT permission for each of the component SELECT statements.

Side effects

None.

 Description

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.

If corresponding items in two select lists have different data types, SQL Anywhere will choose a data type for the corresponding column in the result and automatically convert the columns in each component SELECT statement appropriately.

If ORDER BY is used, only integers are allowed in the order by list. These integers specify the position of the columns to be sorted.

The column names displayed are the same column names which would be displayed for the first SELECT statement.


UNLOAD TABLE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

UNLOAD TABLE statement

Function

To export data from a database table into an external ascii-format file.

Syntax

UNLOAD [ FROM ] TABLE [ owner ].table-name

... TO 'filename-string'

... [ FORMAT 'ascii'] [ DELIMITED BY string ]

... [ QUOTES ON | OFF ] [ ESCAPES ON | OFF ]

... [ ORDER ON | OFF ]

... [ ESCAPE CHARACTER character ]

Usage

Anywhere.

Permissions

Must have SELECT permission on the table.

Side effects

None.

 Description

The UNLOAD TABLE statement allows efficient mass exporting from a database table into an ascii file. UNLOAD TABLE is more efficient than the ISQL statement OUTPUT and can be called from any client application.

UNLOAD TABLE places an exclusive lock on the whole table.

For descriptions of the FORMAT, DELIMITED BY, and ESCAPE CHARACTER options, see "LOAD TABLE statement". The other options are as follows:

QUOTES option   With QUOTES turned on (the default), single quotes are placed around all exported strings.

ESCAPES option   With ESCAPES on (the default), backslash-character combinations are used to identify special characters where necessary on export.

ORDER option   With ORDER on (the default) the data is exported 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.


UPDATE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

UPDATE statement

Function

To modify data in the database.

Syntax

Syntax 1.

UPDATE table-list

...    SET column-name = expression, ...

...    [ FROM table-list ]

...    [ WHERE search-condition ]

...    [ ORDER BY expression [ ASC | DESC ] ,... ]

Syntax 2.

UPDATE table-list

...    SET column-name = expression, ...

...    [ VERIFY ( column-name, ... ) VALUES ( expression, ... ) ]

...    [ WHERE search-condition ]

...    [ ORDER BY expression [ ASC | DESC ] ,... ]

Syntax 3:

UPDATE table

...PUBLICATION publication

...{ SUBSCRIBE BY expression

   | OLD SUBSCRIBE BY expression  NEW SUBSCRIBE BY expression

   }

...WHERE search-condition

Usage

Syntax 1 can be used Anywhere.

.Syntax 2 and Syntax 3 are applicable only to SQL Remote. Syntax 3 is for use inside a BEFORE trigger.

Permissions

Must have UPDATE permission for the columns being modified.

Side effects

None.

 Description

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. For a description of the table list and how to do joins, see "FROM clause"

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.

Updates based on joins

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.

  For a full description of the FROM clause and joins, see "FROM clause".

SQL Remote updates

Syntax 2 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.

Syntax 3 is intended for use with SQL Remote only, inside a BEFORE trigger. 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 engine 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 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 engine 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 SUBSCRIBE BY expression is either a value or a subquery.

Using UPDATE to maintain subscriptions

Syntax 3 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 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.

  For a full description of this feature, see "Using subqueries in publications ".

Syntax 3 of the UPDATE statement makes an entry in the transaction log, but does not change the database table.


UPDATE (positioned) statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

UPDATE (positioned) statement

Function

To modify the data at the current location of a cursor.

Syntax

Syntax 1:

UPDATE WHERE CURRENT OF cursor-name

... { USING DESCRIPTOR sqlda-name | FROM host-variable-list }

Syntax 2:

UPDATE table-list

... SET column-name = expression, ...

... WHERE CURRENT OF cursor-name

Parameters

host-variable-list:   indicator variables allowed

sqlda-name:   identifier

Usage

Embedded SQL, procedures, triggers, and batches..

The USING DESCRIPTOR, FROM host-variable-list, and host-variable formats are for Embedded SQL only.

Permissions

Must have UPDATE permission on the columns being modified.

Side effects

None.

 Description

This form of the UPDATE statement updates the current row of the specified cursor. The current row is defined to be the last row FETCHed from the cursor and the last operation on the cursor must not have been a DELETE (positioned).

For format 1, columns from the SQLDA or values from the host variable list correspond one-to-one with the select list items of the specified cursor. If the sqldata pointer in the SQLDA is the null pointer, then the corresponding select list item is not updated.

In format 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.

Updating views

Updates are not allowed on cursors on  views that have more than one table in the FROM clause.


VALIDATE TABLE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

VALIDATE TABLE statement

Function

To validate a table in the database.

Syntax

VALIDATE TABLE [ owner.]table-name

Usage

Anywhere.

Permissions

Must be the owner of the table or have DBA authority or have REMOTE DBA authority (SQL Remote).

Side effects

None.

 Description

The VALIDATE TABLE statement will scan every row of a table and look each row up in each index on the table. If the database file is corrupt, an error will be reported. This should not happen. However, because DOS and Windows are unprotected operating environments, other software can corrupt memory used by the database engine. This problem may be detected through software errors or crashes, or the corrupt memory could get written to the database creating a corrupt database file. Also, in any operating system, hardware problems with the disk could cause the database file to get corrupted.

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.


WHENEVER statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 41. Watcom-SQL Statements

WHENEVER statement

Function

To specify error handling in an Embedded SQL program.

Syntax

WHENEVER

  SQLERROR

| SQLWARNING

| NOTFOUND

...

 GOTO label

| STOP

| CONTINUE

| { C code; }

Parameters

label:   identifier

Usage

Embedded SQL.

Permissions

None.

Side effects

None.

Description

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 C 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 and not 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.


SQL Anywhere Database Error Messages
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

About this chapter

This chapter lists all database error messages reported by SQL 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 message index by SQLCODE

 Error messages index by SQLSTATE

 Alphabetic list of error messages

 Internal errors (assertion failed)


Error message index by SQLCODE
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Error message index by SQLCODE

SQLCODE	Message
-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 view '%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	A parameter to an external function is an unsupported datatype
-623	Data definition statements not allowed in procedures or triggers
-622	Could not allocate resources to call external function
-621	Could not find the named function in the dynamic library
-620	Could not load the dynamic library
-619	Need a dynamic library name
-618	Mismatch between external function platform specifier and current operating system
-617	Calling functions outside the database engine 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 datatypes
-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 datatype for column in WRITETEXT or READTEXT
-608	Invalid TEXTPTR value used with WRITETEXT or READTEXT
-407	An argument passed to a SQL Anywhere HLI function was invalid
-406	SQL Anywhere HLI internal error
-405	Invalid SQL Anywhere HLI callback function
-404	Invalid SQL Anywhere HLI host variable value
-403	Invalid SQL Anywhere HLI host variable name
-402	Invalid SQL Anywhere HLI statement name
-401	Invalid SQL Anywhere HLI cursor name
-400	Invalid SQL Anywhere HLI command syntax
-312	User '%1' already has membership in group '%2'
-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
-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 signalled
-296	Error number %1 for RAISERROR  is less than 17000
-295	Cannot uniquely identify rows in cursor
-294	Format string argument number %1 is invalid
-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 engine
-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 engine
-269	Cannot delete a column referenced in a trigger definition
-268	Trigger '%1' not found
-267	COMMIT/ROLLBACK not allowed within atomic operation
-266	Database was initialized with an older version of the software
-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
-245	Integrated logon 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
-232	Server/database engine version mismatch
-231	Dblib/database engine 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
-215	Procedure in use
-214	Table in use
-213	Savepoints require a rollback log
-212	CHECKPOINT command requires a rollback log
-211	Not allowed while %1 is using the database
-210	User '%1' has the row in '%2' locked
-209	Invalid value for column '%1' in table '%2'
-208	Row has changed since last read -- operation cancelled
-207	Wrong number of values for INSERT
-206	Standard logons are not permitted
-205	Integrated logons 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 in another table
-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	Invalid operation for this cursor
-186	Subquery cannot return more than one result
-185	SELECT returns more than one row
-184	Error inserting into cursor
-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
-162	Cannot outer join a view with a UNION or GROUP BY
-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 do not match in length
-152	Number in ORDER BY is too large
-151	Subquery allowed only one select list item
-150	Aggregate functions not allowed on this statement
-149	Function or column reference to '%1' in the select list 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	Userid '%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'
-130	Invalid statement
-128	Cannot drop a user that owns tables in runtime engine
-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	Do not have permission to %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 does not match SELECT
-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 log file
-106	Cannot open log file %1
-105	Cannot be started -- %1
-104	Invalid userid and password on preprocessed module
-103	Invalid userid or password
-102	Too many connections to database
-101	Not connected to SQL database
-100	Database engine not running
-99	Connections to database have been disabled
-98	Authentication violation
-97	Database's page size too big
-96	Database engine already running
-95	Invalid parameter
-89	Database engine not running in multiuser mode
-88	Client/server communications protocol mismatch
-87	Database name required to start engine
-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
-81	Invalid database engine command line
-80	Unable to start database engine
-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
-73	Communication buffer underflow
0	(no message)
100	No data
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
108	Cursor operation conflict
109	Null value eliminated in aggregate function
110	Transaction log backup page only partially full
111	Statement cannot be executed
112	More info required
113	Database option '%1' for user '%2' has an invalid setting
200	Warning
400	The supplied buffer was too small to hold all requested query results


Error messages index by SQLSTATE
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Error messages index by SQLSTATE

SQL 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	Message
00000	(no message)
01000	Warning
01001	Cursor operation conflict
01003	Null value eliminated in aggregate function
01004	Value truncated
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 info required
01W10	Transaction log backup page only partially full
01W11	Database option '%1' for user '%2' has an invalid setting
01WH1	The supplied buffer was too small to hold all requested query results
02W01	No data
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
08001	Cannot be started -- %1
08003	Not connected to SQL database
08004	Userid '%1' does not exist
08W01	Database engine not running
08W02	Connection not found
08W03	Too many connections to database
08W04	Connections to database have been disabled
08W05	Cannot open log file %1
08W06	There are still active database connections
08W07	Unable to start database engine
08W08	Invalid database engine command line
08W09	Unable to start specified database
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 engine
08W15	Client/server communications protocol mismatch
08W16	Database engine not running in multiuser mode
08W17	Error writing to log file
08W18	Sqlpp/dblib version mismatch
08W19	Dblib/database engine version mismatch
08W20	Server/database engine version mismatch
08W21	Authentication violation
08W22	Database's page size too big
08W23	Database engine 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
08W31	Communication buffer underflow
09W01	Error inserting into cursor
09W02	Invalid operation for this cursor
09W04	INSERT/DELETE on cursor can modify only one table
09W05	Cannot uniquely identify rows in cursor
0A000	Feature '%1' not implemented
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 engine
21000	SELECT returns more than one row
21W01	Subquery cannot return more than one result
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'
22W01	An argument passed to a SQL Anywhere HLI function was invalid
22W02	Row has changed since last read -- operation cancelled
22W03	Invalid TE XTPTR value used with WRITETEXT or READTEXT
23502	Column '%1' in table '%2' cannot be NULL
23503	No primary key value for foreign key '%1' in table '%2'
23505	Index '%1' for table '%2' would not be unique
23506	Invalid value for column '%1' in table '%2'
23W01	Primary key for table '%1' is not unique
23W05	Primary key for row in table '%1' is referenced in another table
24501	Cursor not open
24502	Cursor already open
24503	No current row of cursor
24W01	Cursor has not been declared
26501	SQL statement error
26W01	Invalid SQL Anywhere HLI statement name
28000	Invalid userid or password
28W01	Invalid userid and password on preprocessed module
28W02	Integrated logons are not permitted
28W03	Standard logons are not permitted
28W04	Integrated logon failed
2D501	COMMIT/ROLLBACK not allowed within trigger actions
33000	Invalid SQL descriptor name
34W01	Invalid SQL Anywhere HLI cursor name
37505	Wrong number of parameters to function '%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
40W06	All threads are blocked
40W07	Connection was terminated
42501	Do not have permission to %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'
42W05	Unknown function '%1'
42W06	Aggregate functions not allowed on this statement
42W07	Invalid host variable
42W08	Invalid expression near '%1'
42W09	Invalid SQL Anywhere HLI host variable name
42W10	Invalid SQL Anywhere HLI host variable value
42W11	Invalid SQL Anywhere HLI command syntax
42W12	Invalid SQL Anywhere HLI callback function
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 command requires a rollback log
42W21	Table in use
42W22	Attempted two active database requests
42W23	Procedure in use
42W24	Label '%1' not found
42W25	Invalid absolute or relative offset in FETCH
42W26	Wrong number of variables in FETCH
42W27	Database was initialized with an older version of the software
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'
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'
44000	WITH CHECK OPTION violated for view '%1'
52002	Column '%1' found in more than one table -- need a correlation name
52003	Column '%1' not found
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	Cannot outer join a view with a UNION or GROUP BY
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
53002	Wrong number of values for INSERT
53003	Function or column reference to '%1' in the select list must also appear in a GROUP BY
53005	Number in ORDER BY is too large
53011	Number of columns does not match SELECT
53018	Cannot convert %1 to a %2
53023	Subquery allowed only one select list item
53026	SELECT lists in UNION 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 a column referenced in a trigger definition
53W07	Error number %1 for RAISERROR  is less than 17000
53W08	Format string argument number %1 is invalid
53W09	Invalid datatype for column in WRITETEXT or READTEXT
54003	Identifier '%1' too long
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 engine
55W04	Cannot drop a user that owns procedures in runtime engine
55W05	Cannot drop a user that owns messages or datatypes
57014	Statement interrupted by user
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	Pa ssthrough statement inconsistent with current passthrough
5RW09	Remote statement failed
99999	User-defined exception signalled
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
WI005	Unable to find in index '%1' for table '%2'
WI007	SQL Anywhere HLI internal error
WW003	Calling functions outside the database engine is not supported
WW004	Mismatch between external function platform specifier and current operating system
WW005	Need a dynamic library name
WW006	Could not load the dynamic library
WW007	Could not find the named function in the dynamic library
WW008	Could not allocate resources to call external function
WW009	A parameter to an external function is an unsupported datatype
WW010	Too many parameters to this external procedure call
WW011	A thread used internally could not be started
WW012	RAISERROR  executed:  %1


Alphabetic list of error messages
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

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)

 A parameter to an external function is an unsupported datatype

 A thread used internally could not be started

 Aggregate functions not allowed on this statement

 All threads are blocked

 ALTER clause conflict

 An argument passed to a SQL Anywhere HLI function was invalid

 Attempted two active database requests

 Authentication violation

 Calling functions outside the database engine is not supported

 Can only describe a SELECT statement

 Cannot alter a column in an index

 Cannot be started -- %1

 Cannot convert %1 to a %2

 Cannot delete a column referenced in a trigger definition

 Cannot drop a user that owns messages or datatypes

 Cannot drop a user that owns procedures in runtime engine

 Cannot drop a user that owns tables in runtime engine

 Cannot find index named '%1'

 Cannot modify column '%1' in table '%2'

 Cannot open log file %1

 Cannot outer join a view with a UNION or GROUP BY

 Cannot set a temporary option for user '%1'

 Cannot uniquely identify rows in cursor

 Cannot update an expression

 CHECKPOINT command requires a rollback log

 Client/server communications protocol mismatch

 Column %1 in foreign key has a different definition than primary key

 Column '%1' found in more than one table -- need a correlation name

 Column '%1' in table '%2' cannot be NULL

 Column '%1' not found

 COMMIT/ROLLBACK not allowed within atomic operation

 COMMIT/ROLLBACK not allowed within trigger actions

 Communication buffer underflow

 Communication error

 Connection not found

 Connection was terminated

 Connections to database have been disabled

 Correlation name '%1' not found

 Could not allocate resources to call external function

 Could not find the named function in the dynamic library

 Could not load the dynamic library

 Cursor already open

 Cursor has not been declared

 Cursor not open

 Cursor operation conflict

 Data definition statements not allowed in procedures or triggers

 Database backup not started

 Database engine already running

 Database engine not running

 Database engine not running in multiuser mode

 Database name not unique

 Database name required to start engine

 Database option '%1' for user '%2' has an invalid setting

 Database was initialized with an older version of the software

 Database's page size too big

 Dblib/database engine version mismatch

 Dbspace '%1' not found

 Deadlock detected

 Disallowed language extension detected in syntax near '%1'

 Disk full '%1' -- transaction rolled back

 Division by zero

 Do not have permission to %1

 Duplicate insert column

 Duplicate referencing column

 Dynamic memory exhausted!

 Error in assignment

 Error inserting into cursor

 Error number %1 for RAISERROR  is less than 17000

 Error opening cursor

 Error writing to log file

 Feature '%1' not implemented

 Foreign key '%1' for table '%2' duplicates an existing foreign key

 Foreign key name '%1' not found

 Format string argument number %1 is invalid

 Function or column reference to '%1' in the select list must also appear in a GROUP BY

 GRANT of column permission on view not allowed

 I/O error %1 -- transaction rolled back

 Identifier '%1' too long

 Incomplete transactions prevent transaction log renaming

 Index '%1' for table '%2' would not be unique

 Index name '%1' not unique

 INSERT/DELETE on cursor can modify only one table

 Integrated logon failed

 Integrated logons are not permitted

 Internal database error %1 -- transaction rolled back

 Invalid absolute or relative offset in FETCH

 Invalid column number

 Invalid data conversion

 Invalid database engine command line

 Invalid datatype for column in WRITETEXT or READTEXT

 Invalid descriptor index

 Invalid escape character '%1'

 Invalid escape sequence '%1'

 Invalid expression near '%1'

 Invalid host variable

 Invalid local database switch

 Invalid operation for this cursor

 Invalid option '%1' -- no PUBLIC setting exists

 Invalid parameter

 Invalid prepared statement type

 Invalid REFERENCES clause in trigger definition

 Invalid setting for option '%1'

 Invalid SQL Anywhere HLI callback function

 Invalid SQL Anywhere HLI command syntax

 Invalid SQL Anywhere HLI cursor name

 Invalid SQL Anywhere HLI host variable name

 Invalid SQL Anywhere HLI host variable value

 Invalid SQL Anywhere HLI statement name

 Invalid SQL descriptor name

 Invalid statement

 Invalid TEXTPTR value used with WRITETEXT or READTEXT

 Invalid type on DESCRIBE statement

 Invalid userid and password on preprocessed module

 Invalid userid or password

 Invalid value for column '%1' in table '%2'

 Item '%1' already exists

 Label '%1' not found

 Language extension

 Language extension detected in syntax

 Mismatch between external function platform specifier and current operating system

 More columns are being dropped from table %1 than are defined

 More info required

 More than one table is identified as '%1'

 Need a dynamic library name

 No current row of cursor

 No data

 No indicator variable provided for NULL result

 No primary key value for foreign key '%1' in table '%2'

 Not allowed while %1 is using the database

 Not connected to SQL database

 Not enough fields allocated in SQLDA

 Not enough memory to start

 Not enough values for host variables

 Null value eliminated in aggregate function

 Number in ORDER BY is too large

 Number of columns does not match SELECT

 Only PUBLIC settings are allowed for option '%1'

 Only the DBA can set the option %1

 Operation would cause a group cycle

 Parameter '%1' not found in procedure '%2'

 Parameter name missing in call to procedure '%1'

 Passthrough statement inconsistent with current passthrough

 Primary key column '%1' already defined

 Primary key for row in table '%1' is referenced in another table

 Primary key for table '%1' is not unique

 Procedure '%1' not found

 Procedure has completed

 Procedure in use

 Procedure or trigger calls have nested too deeply

 Publication '%1' not found

 RAISERROR  executed:  %1

 Remote message type '%1' not found

 Remote statement failed

 Request denied -- no active databases

 Request to start/stop database denied

 Result set not allowed from within an atomic compound statement

 Right truncation of string data

 ROLLBACK TO SAVEPOINT not allowed

 Row has been updated since last time read

 Row has changed since last read -- operation cancelled

 Run time SQL error  --  %1

 Savepoint '%1' not found

 Savepoints require a rollback log

 SELECT lists in UNION do not match in length

 SELECT returns more than one row

 Server/database engine version mismatch

 Specified database is invalid

 Specified database not found

 SQL Anywhere HLI internal error

 SQL statement error

 Sqlpp/dblib version mismatch

 Standard logons are not permitted

 Statement cannot be executed

 Statement interrupted by user

 Subquery allowed only one select list item

 Subquery cannot return more than one result

 Subscription to '%1' for '%2' already exists

 Subscription to '%1' for '%2' not found

 Syntax error near '%1'

 Table '%1' has no primary key

 Table '%1' has publications

 Table '%1' is in an outer join cycle

 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

 Terminated by user -- transaction rolled back

 The selected database is currently inactive

 The supplied buffer was too small to hold all requested query results

 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'

 Too many columns in table

 Too many connections to database

 Too many parameters to this external procedure call

 Transact-SQL feature not supported

 Transaction log backup page only partially full

 Transaction log was truncated

 Trigger '%1' not found

 Trigger definition conflicts with existing triggers

 Triggers and procedures not supported in runtime engine

 Unable to delete database file

 Unable to find in index '%1' for table '%2'

 Unable to start database engine

 Unable to start specified database

 Unknown backup operation

 Unknown function '%1'

 Unterminated C string

 Update operation attempted on a read-only cursor

 Update operation attempted on non-updatable query

 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 message %1 already exists

 User message %1 not found

 User-defined exception signalled

 User-defined type %1 not found

 Userid '%1' does not exist

 Using temporary table

 Value %1 out of range for destination

 Value for column '%1' in table '%2' has changed

 Value truncated

 Variable '%1' not found

 Warning

 WITH CHECK OPTION violated for view '%1'

 Wrong number of parameters to function '%1'

 Wrong number of values for INSERT

 Wrong number of variables in FETCH


(no message)
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

(no message)

Item	Value
SQLCode	0
Constant	SQLE_NOERROR
SQLState	00000
ODBC State	00000
Probable cause

This code indicates that there was no error or warning.


A parameter to an external function is an unsupported datatype
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

A parameter to an external function is an unsupported datatype

Item	Value
SQLCode	-624
Constant	SQLE_DATATYPE_NOT_ALLOWED
SQLState	WW009
ODBC State	S1000
Probable cause

A parameter to a call to an external function is declared to be a datatype that is not supported.


A thread used internally could not be started
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

A thread used internally could not be started

Item	Value
SQLCode	-626
Constant	SQLE_THREAD_START_FAILURE
SQLState	WW011
ODBC State	S1000
Probable cause

This is a Windows95 specific error. An operating system thread could not be started that is required to execute external functions.


Aggregate functions not allowed on this statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Aggregate functions not allowed on this statement

Item	Value
SQLCode	-150
Constant	SQLE_AGGREGATES_NOT_ALLOWED
SQLState	42W06
ODBC State	37000
Probable cause

An UPDATE statement has used an aggregate function (MIN, MAX, SUM, AVG or COUNT).


All threads are blocked
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

All threads are blocked

Item	Value
SQLCode	-307
Constant	SQLE_THREAD_DEADLOCK
SQLState	40W06
ODBC State	40001
Probable cause

You have attempted to read or write a row and it is locked by another user.  Also, all other threads (see database option THREAD_COUNT) 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
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

ALTER clause conflict

Item	Value
SQLCode	-125
Constant	SQLE_ALTER_CLAUSE_CONFLICT
SQLState	53W01
ODBC State	S1000
Probable cause

A primary key clause, foreign key clause, or a uniqueness clause must be the only clause of an ALTER TABLE command.


An argument passed to a SQL Anywhere HLI function was invalid
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

An argument passed to a SQL Anywhere HLI function was invalid

Item	Value
SQLCode	-407
Constant	SQLE_HLI_BAD_ARGUMENT
SQLState	22W01
ODBC State	22W01
Probable cause

One of the arguments passed to a WSQL HLI function was invalid.  This may indicate that a pointer to a command string or result buffer is the null pointer.


Attempted two active database requests
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Attempted two active database requests

Item	Value
SQLCode	-298
Constant	SQLE_DOUBLE_REQUEST
SQLState	42W22
ODBC State	S1000
Probable cause

In Embedded SQL, you have 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 violation
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Authentication violation

Item	Value
SQLCode	-98
Constant	SQLE_AUTHENTICATION_VIOLATION
SQLState	08W21
ODBC State	08001
Probable cause

You have attempted to connect to an engine or server which has been authenticated for exclusive use with a specific application.


Calling functions outside the database engine is not supported
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Calling functions outside the database engine is not supported

Item	Value
SQLCode	-617
Constant	SQLE_EXTERNAL_CALLS_NOT_SUPPORTED
SQLState	WW003
ODBC State	S1000
Probable cause

An attempt was made 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
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Can only describe a SELECT statement

Item	Value
SQLCode	-160
Constant	SQLE_DESCRIBE_NONSELECT
SQLState	07005
ODBC State	(handled by ODBC driver)
Probable cause

In the C language interface, you attempted to describe the select list of a statement other than a SELECT statement.


Cannot alter a column in an index
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Cannot alter a column in an index

Item	Value
SQLCode	-127
Constant	SQLE_COLUMN_IN_INDEX
SQLState	53W05
ODBC State	S1000
Probable cause

This error is reported if you attempt to delete or modify the definition of a column that is part of a primary or foreign key. This error will also be reported if you attempt to delete a column that has an index on it. DROP the index or key, perform the ALTER command, and then add the index or key again.


Cannot be started -- %1
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Cannot be started -- %1

Item	Value
SQLCode	-105
Constant	SQLE_UNABLE_TO_CONNECT
SQLState	08001
ODBC State	08001
Parameter 1	Name of database.
Probable cause

The specified database environment cannot be found. If it is a database name, then it does not exist, it is not a database, it is corrupt, or it is an older format. If it is a server name, then the server cannot be found.


Cannot convert %1 to a %2
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Cannot convert %1 to a %2

Item	Value
SQLCode	-157
Constant	SQLE_CONVERSION_ERROR
SQLState	53018
ODBC State	07006
Parameter 1	The value that could not be converted.
Parameter 2	The name of the type for the conversion.
Probable cause

An invalid value has been supplied to or fetched from the database. For example, the value 12X might have been supplied where a number was required.


Cannot delete a column referenced in a trigger definition
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Cannot delete a column referenced in a trigger definition

Item	Value
SQLCode	-269
Constant	SQLE_COLUMN_IN_TRIGGER
SQLState	53W06
ODBC State	S1000
Probable cause

This error is reported if you attempt to delete a column that is referenced in a trigger definition. DROP the trigger before performing the ALTER command.


Cannot drop a user that owns messages or datatypes
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Cannot drop a user that owns messages or datatypes

Item	Value
SQLCode	-614
Constant	SQLE_USER_OWNS_MESSAGES_OR_DATATYPES
SQLState	55W05
ODBC State	37000
Probable cause

A user to be dropped is the creator of a message or user-defined datatype.  The message or user-defined datatype must be dropped first.


Cannot drop a user that owns procedures in runtime engine
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Cannot drop a user that owns procedures in runtime engine

Item	Value
SQLCode	-270
Constant	SQLE_USER_OWNS_PROCEDURES
SQLState	55W04
ODBC State	37000
Probable cause

This error is reported by the runtime engine if you attempt to drop a user that owns procedures.  Because this operation would result in dropping procedures, and the runtime engine cannot drop procedures, it is not allowed.  Use the full engine.


Cannot drop a user that owns tables in runtime engine
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Cannot drop a user that owns tables in runtime engine

Item	Value
SQLCode	-128
Constant	SQLE_USER_OWNS_TABLES
SQLState	55W03
ODBC State	37000
Probable cause

This error is reported by the runtime engine if you attempt to drop a user that owns tables.  Because this operation would result in dropping tables, and the runtime engine cannot drop tables, it is not allowed.  Use the full engine.


Cannot find index named '%1'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Cannot find index named '%1'

Item	Value
SQLCode	-183
Constant	SQLE_INDEX_NOT_FOUND
SQLState	52W03
ODBC State	S0012
Parameter 1	Name of the index that cannot be found.
Probable cause

A DROP INDEX command has named an index that does not exist. Check for spelling errors or whether the index name must be qualified by a userid.


Cannot modify column '%1' in table '%2'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Cannot modify column '%1' in table '%2'

Item	Value
SQLCode	-191
Constant	SQLE_CANNOT_MODIFY
SQLState	42W32
ODBC State	42032
Parameter 1	Name of the column that cannot be changed.
Parameter 2	Name of the table containing the column.
Probable cause

You do not have permission to modify the column, or the table is actually a view and the column in the view is defined as an expression (such as column1+column2) that cannot be modified.


Cannot open log file %1
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Cannot open log file %1

Item	Value
SQLCode	-106
Constant	SQLE_CANNOT_OPEN_LOG
SQLState	08W05
ODBC State	08003
Parameter 1	Name of log file.
Probable cause

The database engine was unable to open the transaction log file.  Perhaps the log file name specifies 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 outer join a view with a UNION or GROUP BY
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Cannot outer join a view with a UNION or GROUP BY

Item	Value
SQLCode	-162
Constant	SQLE_CANNOT_OUTER_JOIN
SQLState	52W19
ODBC State	37000
Probable cause

A view that contains a UNION or view cannot be used on the right of a LEFT OUTER JOIN or on the left of a RIGHT OUTER JOIN.


Cannot set a temporary option for user '%1'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Cannot set a temporary option for user '%1'

Item	Value
SQLCode	-203
Constant	SQLE_TEMPORARY_NOT_ALLOWED
SQLState	42W45
ODBC State	37000
Parameter 1	Userid whose option was to be changed.
Probable cause

TEMPORARY options are set on a connection basis. To change an option for another user, do not specify TEMPORARY in the SET OPTION statement.


Cannot uniquely identify rows in cursor
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Cannot uniquely identify rows in cursor

Item	Value
SQLCode	-295
Constant	SQLE_CANNOT_UNIQUELY_IDENTIFY_ROWS
SQLState	09W05
ODBC State	24000
Probable cause

A UNIQUE cursor has been opened 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 or GROUP BY.


Cannot update an expression
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Cannot update an expression

Item	Value
SQLCode	-190
Constant	SQLE_NON_UPDATEABLE_COLUMN
SQLState	53W02
ODBC State	37000
Probable cause

You have tried to update a column in a query that is a database expression rather than a column in a table.


CHECKPOINT command requires a rollback log
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

CHECKPOINT command requires a rollback log

Item	Value
SQLCode	-212
Constant	SQLE_CHECKPOINT_REQUIRES_UNDO
SQLState	42W20
ODBC State	40001
Probable cause

You cannot use a CHECKPOINT command when the database engine is running in bulk mode without a rollback log.


Client/server communications protocol mismatch
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Client/server communications protocol mismatch

Item	Value
SQLCode	-88
Constant	SQLE_PROTOCOL_MISMATCH
SQLState	08W15
ODBC State	08S01
Probable cause

The multiuser client was unable to start because the protocol versions of the client and the running server do not match. Make sure the client and server software are the same version.


Column %1 in foreign key has a different definition than primary key
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Column %1 in foreign key has a different definition than primary key

Item	Value
SQLCode	-113
Constant	SQLE_INVALID_FOREIGN_KEY_DEF
SQLState	53030
ODBC State	23000
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' found in more than one table -- need a correlation name
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Column '%1' found in more than one table -- need a correlation name

Item	Value
SQLCode	-144
Constant	SQLE_COLUMN_AMBIGUOUS
SQLState	52002
ODBC State	SJS01
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 table '%2' cannot be NULL
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Column '%1' in table '%2' cannot be NULL

Item	Value
SQLCode	-195
Constant	SQLE_COLUMN_CANNOT_BE_NULL
SQLState	23502
ODBC 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' not found
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Column '%1' not found

Item	Value
SQLCode	-143
Constant	SQLE_COLUMN_NOT_FOUND
SQLState	52003
ODBC State	S0022
Parameter 1	Name of the column that could not be found.
Probable cause

You have misspelled the name of a column, or the column you are looking for is in a different table.


COMMIT/ROLLBACK not allowed within atomic operation
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

COMMIT/ROLLBACK not allowed within atomic operation

Item	Value
SQLCode	-267
Constant	SQLE_ATOMIC_OPERATION
SQLState	42W28
ODBC State	37000
Probable cause

A COMMIT or ROLLBACK statement was encountered while executing within an atomic operation.


COMMIT/ROLLBACK not allowed within trigger actions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

COMMIT/ROLLBACK not allowed within trigger actions

Item	Value
SQLCode	-273
Constant	SQLE_INVALID_TRIGGER_STATEMENT
SQLState	2D501
ODBC State	37000
Probable cause

An attempt was made to execute a statement that is not allowed while performing a trigger action.  COMMIT and ROLLBACK statements cannot be executed from a trigger.


Communication buffer underflow
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Communication buffer underflow

Item	Value
SQLCode	-73
Constant	SQLE_COMMUNICATIONS_UNDERFLOW
SQLState	08W31
ODBC State	08S01
Probable cause

The multiuser client or server has received a network buffer containing insufficient data. If this error occurs, it should be reported to Watcom.


Communication error
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Communication error

Item	Value
SQLCode	-85
Constant	SQLE_COMMUNICATIONS_ERROR
SQLState	08W12
ODBC State	08S01
Probable cause

There is a communication problem between the multiuser client and server. This happens most frequently when the multiuser client was unable to start because a communication error occurred while trying to locate the server.


Connection not found
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Connection not found

Item	Value
SQLCode	-108
Constant	SQLE_CONNECTION_NOT_FOUND
SQLState	08W02
ODBC State	08003
Probable cause

The specified connection name on a DISCONNECT or SET CONNECTION statement is invalid.


Connection was terminated
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Connection was terminated

Item	Value
SQLCode	-308
Constant	SQLE_CONNECTION_TERMINATED
SQLState	40W07
ODBC State	S1000
Probable cause

Your database connection has been terminated by a DBA executing a DROP CONNECTION command.  Your transaction was rolled back.


Connections to database have been disabled
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Connections to database have been disabled

Item	Value
SQLCode	-99
Constant	SQLE_CONNECTIONS_DISABLED
SQLState	08W04
ODBC State	08005
Probable cause

Connections to the multiuser server have been disabled on the server console.  You will receive this error until they have been reenabled on the server console.


Correlation name '%1' not found
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Correlation name '%1' not found

Item	Value
SQLCode	-142
Constant	SQLE_CORRELATION_NAME_NOT_FOUND
SQLState	52W02
ODBC State	S0002
Parameter 1	Name of the invalid correlation name.
Probable cause

You have misspelled a correlation name, or you have used a table name instead of the correlation name.


Could not allocate resources to call external function
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Could not allocate resources to call external function

Item	Value
SQLCode	-622
Constant	SQLE_ERROR_CALLING_FUNCTION
SQLState	WW008
ODBC State	S1000
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 find the named function in the dynamic library
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Could not find the named function in the dynamic library

Item	Value
SQLCode	-621
Constant	SQLE_COULD_NOT_FIND_FUNCTION
SQLState	WW007
ODBC State	S1000
Probable cause

The external function could not be found in the dynamic library.


Could not load the dynamic library
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Could not load the dynamic library

Item	Value
SQLCode	-620
Constant	SQLE_COULD_NOT_LOAD_LIBRARY
SQLState	WW006
ODBC State	S1000
Probable cause

The library named in an external function call could not be loaded.


Cursor already open
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Cursor already open

Item	Value
SQLCode	-172
Constant	SQLE_CURSOR_ALREADY_OPEN
SQLState	24502
ODBC State	24000
Probable cause

You attempted to OPEN a cursor that is already open.


Cursor has not been declared
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Cursor has not been declared

Item	Value
SQLCode	-170
Constant	SQLE_CURSOR_NOT_DECLARED
SQLState	24W01
ODBC State	24000
Probable cause

You attempted to OPEN a cursor that has not been declared.


Cursor not open
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Cursor not open

Item	Value
SQLCode	-180
Constant	SQLE_CURSOR_NOT_OPEN
SQLState	24501
ODBC State	34000
Probable cause

You attempted to OPEN a cursor that has not been declared.


Cursor operation conflict
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Cursor operation conflict

Item	Value
SQLCode	108
Constant	SQLE_CURSOR_OPERATION_CONFLICT
SQLState	01001
ODBC State	(handled by ODBC driver)
Probable cause

You have attempted to perform an operation on the current row of a cursor, but the row has been modified by a searched UPDATE or DELETE or by a positioned UPDATE or DELETE.


Data definition statements not allowed in procedures or triggers
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Data definition statements not allowed in procedures or triggers

Item	Value
SQLCode	-623
Constant	SQLE_DDL_NOT_ALLOWED_IN_PROCEDURES
SQLState	52W21
ODBC State	S1000
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 backup not started
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Database backup not started

Item	Value
SQLCode	-241
Constant	SQLE_BACKUP_NOT_STARTED
SQLState	WB002
ODBC State	S1000
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 engine already running
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Database engine already running

Item	Value
SQLCode	-96
Constant	SQLE_ENGINE_ALREADY_RUNNING
SQLState	08W23
ODBC State	S1000
Probable cause

The database engine was not able to start on a db_start_engine call because it was already running.


Database engine not running
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Database engine not running

Item	Value
SQLCode	-100
Constant	SQLE_ENGINE_NOT_RUNNING
SQLState	08W01
ODBC State	08001
Probable cause

You have not run the database engine or network requestor or the interface library is unable to find it.


Database engine not running in multiuser mode
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Database engine not running in multiuser mode

Item	Value
SQLCode	-89
Constant	SQLE_ENGINE_NOT_MULTIUSER
SQLState	08W16
ODBC State	08001
Probable cause

The database was started for bulk loading (the -b switch) and cannot be used as a multiuser engine. Stop the database, and start again without -b. In the DOS version of Watcom SQL 3.0, the database engine was not started in multiuser mode.


Database name not unique
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Database name not unique

Item	Value
SQLCode	-77
Constant	SQLE_ALIAS_CLASH
SQLState	08W27
ODBC State	08001
Probable cause

The database cannot be loaded as its name is conflicting with a previously loaded database.


Database name required to start engine
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Database name required to start engine

Item	Value
SQLCode	-87
Constant	SQLE_DATABASE_NAME_REQUIRED
SQLState	08W14
ODBC State	08001
Probable cause

A database name is required to start the database engine or the multiuser client, but it was not specified.


Database option '%1' for user '%2' has an invalid setting
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Database option '%1' for user '%2' has an invalid setting

Item	Value
SQLCode	113
Constant	SQLE_INVALID_OPTION_ON_CONNECT
SQLState	01W11
ODBC State	(handled by ODBC driver)
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 engine processed a database option from the SYSOPTIONS table which had an invalid setting. The erroneous option setting is ignored; in its place, the engine will use the default option value for the current database.


Database was initialized with an older version of the software
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Database was initialized with an older version of the software

Item	Value
SQLCode	-266
Constant	SQLE_OLD_DBINIT
SQLState	42W27
ODBC State	37000
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 SQL Anywhere or use DBUPGRADE to upgrade the database to the most recent version.


Database's page size too big
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Database's page size too big

Item	Value
SQLCode	-97
Constant	SQLE_PAGE_SIZE_TOO_BIG
SQLState	08W22
ODBC State	08004
Probable cause

You have attempted to start a database with a page size that exceeds the maximum page size of the running engine. Restart the engine with this database named on the command line.


Dblib/database engine version mismatch
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Dblib/database engine version mismatch

Item	Value
SQLCode	-231
Constant	SQLE_DBLIB_ENGINE_MISMATCH
SQLState	08W19
ODBC State	08001
Probable cause

Your executable uses a database interface library that does not match the version number of the database engine.


Dbspace '%1' not found
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Dbspace '%1' not found

Item	Value
SQLCode	-138
Constant	SQLE_DBSPACE_NOT_FOUND
SQLState	52W13
ODBC State	S0002
Parameter 1	Name of the dbspace that could not be found.
Probable cause

The named dbspace was not found.


Deadlock detected
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Deadlock detected

Item	Value
SQLCode	-306
Constant	SQLE_DEADLOCK
SQLState	40001
ODBC State	40001
Probable cause

You have 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.


Disallowed language extension detected in syntax near '%1'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Disallowed language extension detected in syntax near '%1'

Item	Value
SQLCode	-627
Constant	SQLE_INVALID_SYNTAX_EXTENSION
SQLState	0AW03
ODBC State	S1000
Parameter 1	The word or symbol where the syntax has been detected.
Probable cause

The command you are trying to execute contains extensions to ANSI 1992 Entry SQL that are not allowed by the current settings.


Disk full '%1' -- transaction rolled back
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Disk full '%1' -- transaction rolled back

Item	Value
SQLCode	-304
Constant	SQLE_DEVICE_FULL
SQLState	40W03
ODBC State	S1000
Probable cause

Your hard disk is out of free space. A ROLLBACK WORK command has been automatically executed.


Division by zero
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Division by zero

Item	Value
SQLCode	-628
Constant	SQLE_DIV_ZERO_ERROR
SQLState	22012
ODBC State	22012
Probable cause

A division by zero operation was detected.


Do not have permission to %1
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Do not have permission to %1

Item	Value
SQLCode	-121
Constant	SQLE_PERMISSION_DENIED
SQLState	42501
ODBC 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. You have not been granted permission to use a table belonging to another userid.


Duplicate insert column
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Duplicate insert column

Item	Value
SQLCode	-637
Constant	SQLE_DUPLICATE_INSERT_COLUMN
SQLState	42W41
ODBC State	42000
Probable cause

A duplicate column name was used in the list of insert columns.


Duplicate referencing column
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Duplicate referencing column

Item	Value
SQLCode	-636
Constant	SQLE_DUPLICATE_REFERENCING_COLUMN
SQLState	42W40
ODBC State	42000
Probable cause

A duplicate column name was used in the list of referencing columns.


Dynamic memory exhausted!
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Dynamic memory exhausted!

Item	Value
SQLCode	-78
Constant	SQLE_DYNAMIC_MEMORY_EXHAUSTED
SQLState	08W26
ODBC State	S1001
Probable cause

A failure occurred when trying to allocate dynamic memory.


Error in assignment
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Error in assignment

Item	Value
SQLCode	-641
Constant	SQLE_ERROR_IN_ASSIGNMENT
SQLState	22005
ODBC State	22005
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 inserting into cursor
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Error inserting into cursor

Item	Value
SQLCode	-184
Constant	SQLE_PUT_CURSOR_ERROR
SQLState	09W01
ODBC State	S1000
Probable cause

An error has occurred while inserting into a cursor.


Error number %1 for RAISERROR  is less than 17000
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Error number %1 for RAISERROR  is less than 17000

Item	Value
SQLCode	-296
Constant	SQLE_ERROR_NUMBER_OUT_OF_RANGE
SQLState	53W07
ODBC State	37000
Parameter 1	Error number.
Probable cause

The error number used in a RAISERROR  statement is invalid. The number must be greater than or equal to 17000.


Error opening cursor
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Error opening cursor

Item	Value
SQLCode	-171
Constant	SQLE_OPEN_CURSOR_ERROR
SQLState	07003
ODBC State	24000
Probable cause

You have attempted to open a cursor on a statement that is not a SELECT statement or a CALL statement.


Error writing to log file
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Error writing to log file

Item	Value
SQLCode	-107
Constant	SQLE_ERROR_WRITING_LOG
SQLState	08W17
ODBC State	S1000
Probable cause

The database engine got an I/O error writing the log file. Perhaps the disk is full or the log file name is invalid.


Feature '%1' not implemented
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Feature '%1' not implemented

Item	Value
SQLCode	-134
Constant	SQLE_NOT_IMPLEMENTED
SQLState	0A000
ODBC State	S1000
Parameter 1	The unimplemented feature.
Probable cause

The requested operation or feature is not implemented in SQL Anywhere.


Foreign key '%1' for table '%2' duplicates an existing foreign key
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Foreign key '%1' for table '%2' duplicates an existing foreign key

Item	Value
SQLCode	-251
Constant	SQLE_DUPLICATE_FOREIGN_KEY
SQLState	52W06
ODBC State	23000
Parameter 1	The role name of the new foreign key.
Parameter 2	The table containing the foreign key.
Probable cause

You have attempted to define a foreign key that already exists.


Foreign key name '%1' not found
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Foreign key name '%1' not found

Item	Value
SQLCode	-145
Constant	SQLE_FOREIGN_KEY_NAME_NOT_FOUND
SQLState	52W07
ODBC State	37000
Parameter 1	Name of the non-existing foreign key.
Probable cause

You have misspelled the name of a foreign key or the foreign key does not exist.


Format string argument number %1 is invalid
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Format string argument number %1 is invalid

Item	Value
SQLCode	-294
Constant	SQLE_INVALID_FORMAT_STRING_ARG_NUM
SQLState	53W08
ODBC State	37000
Parameter 1	Argument number.
Probable cause

An argument number in the format string for a PRINT or RAISERROR statement is invalid.  The number must be between 1 and 20 and must not exceed the number of arguments provided.


Function or column reference to '%1' in the select list must also appear in a GROUP BY
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Function or column reference to '%1' in the select list must also appear in a GROUP BY

Item	Value
SQLCode	-149
Constant	SQLE_INVALID_GROUP_SELECT
SQLState	53003
ODBC State	37000
Parameter 1	Name of the column referenced directly, or in an expression, that must be in the GROUP BY clause.
Probable cause

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, simply 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
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

GRANT of column permission on view not allowed

Item	Value
SQLCode	-635
Constant	SQLE_NO_COLUMN_PERMS_FOR_VIEWS
SQLState	52W22
ODBC State	S1000
Probable cause

Permissions on columns cannot be granted for views.


I/O error %1 -- transaction rolled back
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

I/O error %1 -- transaction rolled back

Item	Value
SQLCode	-305
Constant	SQLE_DEVICE_ERROR
SQLState	40W04
ODBC State	S1000
Probable cause

SQL Anywhere has detected a problem with your hard disk. If you cannot find a hardware error using the operating system disk check utility (eg. in DOS, chkdsk, and in QNX, chkfsys), report the problem to SQL Anywhere technical support. A ROLLBACK WORK command has been automatically executed.


Identifier '%1' too long
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Identifier '%1' too long

Item	Value
SQLCode	-250
Constant	SQLE_IDENTIFIER_TOO_LONG
SQLState	54003
ODBC State	37000
Parameter 1	The identifier in error.
Probable cause

An identifier is longer than 128 characters.


Incomplete transactions prevent transaction log renaming
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Incomplete transactions prevent transaction log renaming

Item	Value
SQLCode	-242
Constant	SQLE_BACKUP_CANNOT_RENAME_LOG_YET
SQLState	WB003
ODBC State	S1000
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.  The db_backup call should be reissued.


Index '%1' for table '%2' would not be unique
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Index '%1' for table '%2' would not be unique

Item	Value
SQLCode	-196
Constant	SQLE_INDEX_NOT_UNIQUE
SQLState	23505
ODBC 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 have inserted or updated 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' not unique
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Index name '%1' not unique

Item	Value
SQLCode	-111
Constant	SQLE_INDEX_NAME_NOT_UNIQUE
SQLState	52W04
ODBC State	S0011
Parameter 1	Name of the invalid index.
Probable cause

You have attempted to create an index with a name of an existing index.


INSERT/DELETE on cursor can modify only one table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

INSERT/DELETE on cursor can modify only one table

Item	Value
SQLCode	-199
Constant	SQLE_ONLY_ONE_TABLE
SQLState	09W04
ODBC State	37000
Probable cause

You have attempted to INSERT into a cursor and have specified values for more than one table; or you have tried 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.


Integrated logon failed
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Integrated logon failed

Item	Value
SQLCode	-245
Constant	SQLE_INTEGRATED_LOGON_FAILED
SQLState	28W04
ODBC State	28000
Probable cause

The integrated logon failed, possibly because if the user doesn't have a system account on the server machine, or for other reasons.


Integrated logons are not permitted
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Integrated logons are not permitted

Item	Value
SQLCode	-205
Constant	SQLE_INVALID_STANDARD_LOGON
SQLState	28W02
ODBC State	28000
Probable cause

The engine logon type switch (gl) is set to STANDARD logon type, and the user has attempted an integrated logon.


Internal database error %1 -- transaction rolled back
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Internal database error %1 -- transaction rolled back

Item	Value
SQLCode	-301
Constant	SQLE_DATABASE_ERROR
SQLState	40W01
ODBC State	S1000
Parameter 1	Identification of the error.
Probable cause

This error indicates an internal database error, and should be reported to SQL Anywhere technical support. A ROLLBACK WORK command has been automatically executed.


Invalid absolute or relative offset in FETCH
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid absolute or relative offset in FETCH

Item	Value
SQLCode	-263
Constant	SQLE_INVALID_FETCH_POSITION
SQLState	42W25
ODBC State	37000
Probable cause

The offset specified in a FETCH was invalid or NULL.


Invalid column number
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid column number

Item	Value
SQLCode	-159
Constant	SQLE_INVALID_COLUMN_NUMBER
SQLState	42W13
ODBC State	S1000
Probable cause

The column number in a GET DATA command is invalid.


Invalid data conversion
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid data conversion

Item	Value
SQLCode	103
Constant	SQLE_CANNOT_CONVERT
SQLState	01W03
ODBC State	07006
Probable cause

The database could not convert a value to the required type. This is either a value supplied to the database on an insert, update or as a host bind variable, or a value retrieved from the database into a host variable or SQLDA.


Invalid database engine command line
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid database engine command line

Item	Value
SQLCode	-81
Constant	SQLE_INVALID_COMMAND_LINE
SQLState	08W08
ODBC State	08001
Probable cause

It was not possible to start the database engine or multiuser client because the command line was invalid. of how the engine is started.


Invalid datatype for column in WRITETEXT or READTEXT
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid datatype for column in WRITETEXT or READTEXT

Item	Value
SQLCode	-609
Constant	SQLE_INVALID_TEXT_IMAGE_DATATYPE
SQLState	53W09
ODBC State	S1000
Probable cause

The column referenced in a WRITETEXT or READTEXT statement is not defined for storing text or image data.


Invalid descriptor index
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid descriptor index

Item	Value
SQLCode	-640
Constant	SQLE_INVALID_DESCRIPTOR_INDEX
SQLState	07009
ODBC State	07009
Probable cause

The index number used with respect to a descriptor area is out of range.


Invalid escape character '%1'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid escape character '%1'

Item	Value
SQLCode	-629
Constant	SQLE_INVALID_ESCAPE_CHAR
SQLState	22019
ODBC State	22019
Probable cause

Escape character string length must be exactly one.


Invalid escape sequence '%1'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid escape sequence '%1'

Item	Value
SQLCode	-630
Constant	SQLE_INVALID_ESCAPE_SEQ
SQLState	22025
ODBC State	22025
Probable cause

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 near '%1'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid expression near '%1'

Item	Value
SQLCode	-156
Constant	SQLE_EXPRESSION_ERROR
SQLState	42W08
ODBC State	37000
Parameter 1	The invalid expression.
Probable cause

You have an expression which the database engine cannot understand. For example, you might have tried to add two dates.


Invalid host variable
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid host variable

Item	Value
SQLCode	-155
Constant	SQLE_VARIABLE_INVALID
SQLState	42W07
ODBC State	37000
Probable cause

A host variable supplied to the database using the C language interface as either a host variable or through an SQLDA is invalid.


Invalid local database switch
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid local database switch

Item	Value
SQLCode	-79
Constant	SQLE_INVALID_LOCAL_OPTION
SQLState	08W25
ODBC State	08001
Probable cause

An invalid local database switch was found in the DBS option.


Invalid operation for this cursor
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid operation for this cursor

Item	Value
SQLCode	-187
Constant	SQLE_CURSOROP_NOT_ALLOWED
SQLState	09W02
ODBC State	24000
Probable cause

An operation that is not allowed was attempted on a cursor.


Invalid option '%1' -- no PUBLIC setting exists
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid option '%1' -- no PUBLIC setting exists

Item	Value
SQLCode	-200
Constant	SQLE_INVALID_OPTION
SQLState	42W16
ODBC State	37000
Parameter 1	Name of the invalid option.
Probable cause

You have probably misspelled the name of an option in the SET OPTION command. You can only define an option for a user if the database administrator has supplied a PUBLIC value for that option.


Invalid parameter
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid parameter

Item	Value
SQLCode	-95
Constant	SQLE_INVALID_PARAMETER
SQLState	08W24
ODBC State	08004
Probable cause

An error occurred while parsing the string parameter associated with one of the entry points: db_start_engine(), db_start_database(), db_stop_engine(), db_stop_database(), db_string_connect().


Invalid prepared statement type
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid prepared statement type

Item	Value
SQLCode	-133
Constant	SQLE_INVALID_STATEMENT_TYPE
SQLState	07W03
ODBC State	S1000
Probable cause

This is an internal C language interface error. If it occurs, it should be reported to SQL Anywhere technical support.


Invalid REFERENCES clause in trigger definition
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid REFERENCES clause in trigger definition

Item	Value
SQLCode	-272
Constant	SQLE_INVALID_TRIGGER_COL_REFS
SQLState	52W12
ODBC State	37000
Probable cause

The REFERENCES clause in a trigger definition is invalid. An OLD correlation name may have been specified in a BEFORE INSERT trigger, or a NEW correlation name may have been specified in an AFTER DELETE trigger.  In both cases, the values do not exist and cannot be referenced.


Invalid setting for option '%1'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid setting for option '%1'

Item	Value
SQLCode	-201
Constant	SQLE_INVALID_OPTION_SETTING
SQLState	42W17
ODBC State	37000
Parameter 1	Name of the invalid option.
Probable cause

You have supplied an invalid value for an option in the SET command. Some options only allow numeric values, while other options only allow the values on and off:evalue..


Invalid SQL Anywhere HLI callback function
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid SQL Anywhere HLI callback function

Item	Value
SQLCode	-405
Constant	SQLE_HLI_BAD_CALLBACK
SQLState	42W12
ODBC State	42W12
Probable cause

WSQL HLI needed to use a callback function, but the function has not been registered using the wsqlregisterfuncs entry point.


Invalid SQL Anywhere HLI command syntax
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid SQL Anywhere HLI command syntax

Item	Value
SQLCode	-400
Constant	SQLE_HLI_BAD_SYNTAX
SQLState	42W11
ODBC State	42W11
Probable cause

The command string that you sent to wsqlexec cannot be understood. Make sure that all of the keywords in the command string are spelled properly, and that variable names (such as host variable, cursor or statement names) are not too long.


Invalid SQL Anywhere HLI cursor name
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid SQL Anywhere HLI cursor name

Item	Value
SQLCode	-401
Constant	SQLE_HLI_BAD_CURSOR
SQLState	34W01
ODBC State	34W01
Probable cause

The cursor name indicated in your command is not a valid one. For instance, this error would occur if you tried to close a cursor that had never even been declared.


Invalid SQL Anywhere HLI host variable name
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid SQL Anywhere HLI host variable name

Item	Value
SQLCode	-403
Constant	SQLE_HLI_BAD_HOST_VAR_NAME
SQLState	42W09
ODBC State	42W09
Probable cause

You have used a host variable, and the host variable callback function does not recognize it.


Invalid SQL Anywhere HLI host variable value
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid SQL Anywhere HLI host variable value

Item	Value
SQLCode	-404
Constant	SQLE_HLI_BAD_HOST_VAR_VALUE
SQLState	42W10
ODBC State	42W10
Probable cause

You have used a host variable, and the host variable value is too long.


Invalid SQL Anywhere HLI statement name
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid SQL Anywhere HLI statement name

Item	Value
SQLCode	-402
Constant	SQLE_HLI_BAD_STATEMENT
SQLState	26W01
ODBC State	26W01
Probable cause

The statement name indicated in your command is not a valid one. This typically indicates that you have failed to prepare the statement.


Invalid SQL descriptor name
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid SQL descriptor name

Item	Value
SQLCode	-642
Constant	SQLE_INVALID_DESCRIPTOR_NAME
SQLState	33000
ODBC State	33000
Probable cause

You have attempted to deallocate a descriptor which has not been allocated.


Invalid statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid statement

Item	Value
SQLCode	-130
Constant	SQLE_INVALID_STATEMENT
SQLState	07W02
ODBC State	S1000
Probable cause

The statement identifier (generated by PREPARE) passed to the database for a further operation is invalid.


Invalid TEXTPTR value used with WRITETEXT or READTEXT
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid TEXTPTR value used with WRITETEXT or READTEXT

Item	Value
SQLCode	-608
Constant	SQLE_INVALID_TEXTPTR_VALUE
SQLState	22W03
ODBC State	S1000
Probable cause

The value supplied as the TEXTPTR for a WRITETEXT or READTEXT statement is invalid.


Invalid type on DESCRIBE statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid type on DESCRIBE statement

Item	Value
SQLCode	-161
Constant	SQLE_INVALID_DESCRIBE_TYPE
SQLState	07W01
ODBC State	(handled by ODBC driver)
Probable cause

This is an internal C language interface error. If it occurs, it should be reported to SQL Anywhere technical support.


Invalid userid and password on preprocessed module
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid userid and password on preprocessed module

Item	Value
SQLCode	-104
Constant	SQLE_INVALID_MODULE_LOGON
SQLState	28W01
ODBC State	28000
Probable cause

A userid and password were specified when a module was preprocessed but the userid or password is invalid.


Invalid userid or password
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid userid or password

Item	Value
SQLCode	-103
Constant	SQLE_INVALID_LOGON
SQLState	28000
ODBC State	28000
Probable cause

The user has supplied an invalid userid or an incorrect password. ISQL will handle this error by presenting a connection dialog to the user.


Invalid value for column '%1' in table '%2'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Invalid value for column '%1' in table '%2'

Item	Value
SQLCode	-209
Constant	SQLE_INVALID_COLUMN_VALUE
SQLState	23506
ODBC State	23000
Parameter 1	Name of the column that was assigned an invalid value.
Parameter 2	Name of the table containing the column.
Probable cause

An INSERT or UPDATE has specified a value for a column that violates a CHECK constraint, and the INSERT or UPDATE were not done because of the error. Note that a CHECK constraint is violated if it evaluates to FALSE; it is okay if it evaluates to TRUE or UNKNOWN.


Item '%1' already exists
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Item '%1' already exists

Item	Value
SQLCode	-110
Constant	SQLE_NAME_NOT_UNIQUE
SQLState	52010
ODBC State	S0001
Parameter 1	Name of the item that already exists.
Probable cause

You have tried to create a table, view, column, foreign key, or publication with the same name as an existing one.


Label '%1' not found
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Label '%1' not found

Item	Value
SQLCode	-262
Constant	SQLE_LABEL_NOT_FOUND
SQLState	42W24
ODBC State	37000
Parameter 1	Name of the label that could not be found.
Probable cause

The label referenced in a LEAVE statement was not found.


Language extension
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Language extension

Item	Value
SQLCode	-135
Constant	SQLE_LANGUAGE_EXTENSION
SQLState	0AW01
ODBC State	S1000
Probable cause

The requested operation is valid in some versions of SQL, but not in SQL Anywhere.


Language extension detected in syntax
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Language extension detected in syntax

Item	Value
SQLCode	107
Constant	SQLE_SYNTAX_EXTENSION_WARNING
SQLState	01W07
ODBC State	(handled by ODBC driver)
Probable cause

The command you are executing contains extensions to ANSI 1992 Entry SQL.


Mismatch between external function platform specifier and current operating system
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Mismatch between external function platform specifier and current operating system

Item	Value
SQLCode	-618
Constant	SQLE_EXTERNAL_PLATFORM_FAILURE
SQLState	WW004
ODBC State	S1000
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 engine/server is currently executing.


More columns are being dropped from table %1 than are defined
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

More columns are being dropped from table %1 than are defined

Item	Value
SQLCode	-124
Constant	SQLE_TOO_MANY_COLUMNS_DELETED
SQLState	42W44
ODBC 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 info required
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

More info required

Item	Value
SQLCode	112
Constant	SQLE_MORE_INFO
SQLState	01W09
ODBC State	(handled by ODBC driver)
Probable cause

More information is required to complete the request.  This is used internally in the database interface library to process a unified logon.  It should not be returned to an application.


More than one table is identified as '%1'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

More than one table is identified as '%1'

Item	Value
SQLCode	-139
Constant	SQLE_CORRELATION_NAME_AMBIGUOUS
SQLState	52012
ODBC State	SG001
Parameter 1	Ambiguous correlation name.
Probable cause

You have identified two tables in the same FROM clause with the same correlation name.


Need a dynamic library name
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Need a dynamic library name

Item	Value
SQLCode	-619
Constant	SQLE_REQUIRE_DLL_NAME
SQLState	WW005
ODBC State	S1000
Probable cause

The name of the external function to call did not contain a library name specifier.


No current row of cursor
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

No current row of cursor

Item	Value
SQLCode	-197
Constant	SQLE_NO_CURRENT_ROW
SQLState	24503
ODBC State	24000
Probable cause

You have attempted to perform an operation on the current row of a cursor, but there is no current 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 data
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

No data

Item	Value
SQLCode	100
Constant	SQLE_NO_DESCRIPTOR_DATA
SQLState	02W01
ODBC State	02W01
Probable cause

You have positioned a cursor beyond the beginning or past the end of the query.  There is no row at that position. You have attemped to access a descriptor area using an index value larger than the number of variables in the descriptor.


No indicator variable provided for NULL result
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

No indicator variable provided for NULL result

Item	Value
SQLCode	-181
Constant	SQLE_NO_INDICATOR
SQLState	22002
ODBC State	S1000
Probable cause

You tried to retrieve a value from the database that was the NULL value but you did not provide an indicator variable for that value.


No primary key value for foreign key '%1' in table '%2'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

No primary key value for foreign key '%1' in table '%2'

Item	Value
SQLCode	-194
Constant	SQLE_INVALID_FOREIGN_KEY
SQLState	23503
ODBC State	23000
Parameter 1	Name of the foreign key.
Parameter 2	Name of the table with the foreign key.
Probable cause

You have tried to insert or update a row that has a foreign key for another table, and the value for the foreign key is not NULL and there is not a corresponding value in the primary key


Not allowed while %1 is using the database
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Not allowed while %1 is using the database

Item	Value
SQLCode	-211
Constant	SQLE_MUST_BE_ONLY_CONNECTION
SQLState	42W19
ODBC State	40001
Probable cause

You have attempted a data definition language operation that cannot be completed while another is connected.


Not connected to SQL database
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Not connected to SQL database

Item	Value
SQLCode	-101
Constant	SQLE_NOT_CONNECTED
SQLState	08003
ODBC State	08003
Probable cause

You have not connected to the database, or you have executed the DISCONNECT command and have not connected to the database again.


Not enough fields allocated in SQLDA
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Not enough fields allocated in SQLDA

Item	Value
SQLCode	-182
Constant	SQLE_SQLDA_TOO_SMALL
SQLState	07002
ODBC State	07001
Probable cause

There are not enough fields in the SQLDA to retrieve all of the values requested.


Not enough memory to start
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Not enough memory to start

Item	Value
SQLCode	-86
Constant	SQLE_NO_MEMORY
SQLState	08W13
ODBC State	S1001
Probable cause

The database engine or multiuser client executable was loaded but was unable to start because there is not enough memory to run properly.


Not enough values for host variables
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Not enough values for host variables

Item	Value
SQLCode	-188
Constant	SQLE_NOT_ENOUGH_HOST_VARS
SQLState	07001
ODBC State	07001
Probable cause

You have not provided enough host variables for either the number of bind variables, or the command, or the number of select list items.


Null value eliminated in aggregate function
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Null value eliminated in aggregate function

Item	Value
SQLCode	109
Constant	SQLE_NULL_VALUE_ELIMINATED
SQLState	01003
ODBC State	(handled by ODBC driver)
Probable cause

Value of the expression argument of the aggregate function evaluated to NULL for one or more rows.


Number in ORDER BY is too large
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Number in ORDER BY is too large

Item	Value
SQLCode	-152
Constant	SQLE_INVALID_ORDER
SQLState	53005
ODBC State	37000
Probable cause

You have used an integer in an ORDER BY list and the integer is larger than the number of columns in the select list.


Number of columns does not match SELECT
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Number of columns does not match SELECT

Item	Value
SQLCode	-114
Constant	SQLE_VIEW_DEFINITION_ERROR
SQLState	53011
ODBC State	21S01
Probable cause

An INSERT command contains a SELECT with a different number of columns than the INSERT.


Only PUBLIC settings are allowed for option '%1'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Only PUBLIC settings are allowed for option '%1'

Item	Value
SQLCode	-202
Constant	SQLE_NOT_PUBLIC_ID
SQLState	42W43
ODBC State	37000
Parameter 1	Name of the option.
Probable cause

The option specified in the SET OPTION command is PUBLIC only. You cannot define this option for any other user.


Only the DBA can set the option %1
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Only the DBA can set the option %1

Item	Value
SQLCode	-204
Constant	SQLE_OPTION_REQUIRES_DBA
SQLState	42W46
ODBC State	37000
Probable cause

The option specified in the SET OPTION command can only be set by a user having DBA authority.


Operation would cause a group cycle
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Operation would cause a group cycle

Item	Value
SQLCode	-122
Constant	SQLE_GROUP_CYCLE
SQLState	42W02
ODBC State	37000
Probable cause

You have tried to add a member to group that would result in a member belonging to itself (perhaps indirectly).


Parameter '%1' not found in procedure '%2'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Parameter '%1' not found in procedure '%2'

Item	Value
SQLCode	-615
Constant	SQLE_INVALID_PARAMETER_NAME
SQLState	42W47
ODBC State	37000
Probable cause

The procedure parameter name does not match a parameter for this procedure.  Check the spelling of the parameter name.


Parameter name missing in call to procedure '%1'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Parameter name missing in call to procedure '%1'

Item	Value
SQLCode	-639
Constant	SQLE_PARAMETER_NAME_MISSING
SQLState	42W42
ODBC State	37000
Parameter 1	The name of the procedure
Probable cause

Positional arguments were specified after keyword arguments in a call to this procedure.


Passthrough statement inconsistent with current passthrough
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Passthrough statement inconsistent with current passthrough

Item	Value
SQLCode	-287
Constant	SQLE_PASSTHROUGH_INCONSISTENT
SQLState	5RW08
ODBC State	S0002
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.


Primary key column '%1' already defined
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Primary key column '%1' already defined

Item	Value
SQLCode	-119
Constant	SQLE_PRIMARY_KEY_COLUMN_DEFINED
SQLState	52009
ODBC State	23000
Parameter 1	Name of the column that is already in the primary key.
Probable cause

You have listed the same column name twice in the definition of a primary key.


Primary key for row in table '%1' is referenced in another table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Primary key for row in table '%1' is referenced in another table

Item	Value
SQLCode	-198
Constant	SQLE_PRIMARY_KEY_VALUE_REF
SQLState	23W05
ODBC State	23000
Parameter 1	The name of the table with a primary key that is referenced.
Probable cause

You have attempted to delete or modify a primary key that is referenced elsewhere in the database.


Primary key for table '%1' is not unique
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Primary key for table '%1' is not unique

Item	Value
SQLCode	-193
Constant	SQLE_PRIMARY_KEY_NOT_UNIQUE
SQLState	23W01
ODBC State	23000
Parameter 1	Name of the table where the problem was detected.
Probable cause

You have tried to add a new row to a table where 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' not found
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Procedure '%1' not found

Item	Value
SQLCode	-265
Constant	SQLE_PROCEDURE_NOT_FOUND
SQLState	52W09
ODBC State	S0002
Parameter 1	Name of the procedure that could not be found.
Probable cause

You have misspelled the name of a procedure, or you have connected with a different userid and forgotten to qualify a procedure name with a user name.


Procedure has completed
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Procedure has completed

Item	Value
SQLCode	105
Constant	SQLE_PROCEDURE_COMPLETE
SQLState	01W05
ODBC State	(handled by ODBC driver)
Probable cause

An OPEN or a RESUME has caused a procedure to execute to completion. There are no more result sets available from this procedure. This warning will also be returned if you attempt to RESUME a cursor on a SELECT statement.


Procedure in use
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Procedure in use

Item	Value
SQLCode	-215
Constant	SQLE_PROCEDURE_IN_USE
SQLState	42W23
ODBC State	40001
Probable cause

You have attempted to DROP a procedure that is being used by other active users of the database.


Procedure or trigger calls have nested too deeply
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Procedure or trigger calls have nested too deeply

Item	Value
SQLCode	-274
Constant	SQLE_NESTING_TOO_DEEP
SQLState	42W29
ODBC State	37000
Probable cause

You have probably defined a procedure or trigger that causes unlimited recursion.


Publication '%1' not found
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Publication '%1' not found

Item	Value
SQLCode	-280
Constant	SQLE_PUBLICATION_NOT_FOUND
SQLState	5RW01
ODBC State	S0002
Parameter 1	Name of the publication that could not be found.
Probable cause

You have misspelled the name of a publication, or you have connected with a different userid and forgotten to qualify a publication name with a user name.


RAISERROR  executed:  %1
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

RAISERROR  executed:  %1

Item	Value
SQLCode	-631
Constant	SQLE_RAISERROR_STMT
SQLState	WW012
ODBC State	S1000
Parameter 1	RAISERROR  message string
Probable cause

A RAISERROR  statement has been executed.


Remote message type '%1' not found
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Remote message type '%1' not found

Item	Value
SQLCode	-286
Constant	SQLE_NOT_REMOTE_TYPE
SQLState	5RW07
ODBC State	S0002
Parameter 1	Name of remote message type.
Probable cause

You have refered to a remote message type that is not defined in this database. CREATE REMOTE TYPE is used to define remote message types.


Remote statement failed
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Remote statement failed

Item	Value
SQLCode	-288
Constant	SQLE_REMOTE_STATEMENT_FAILED
SQLState	5RW09
ODBC State	S0002
Probable cause

This SQLSTATE can be signalled within a trigger to prevent DBREMOTE from 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
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Request denied -- no active databases

Item	Value
SQLCode	-76
Constant	SQLE_REQUEST_DENIED_NO_DATABASES
SQLState	08W28
ODBC State	08001
Probable cause

The engine has denied the request as there are currently no loaded databases.


Request to start/stop database denied
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Request to start/stop database denied

Item	Value
SQLCode	-75
Constant	SQLE_START_STOP_DATABASE_DENIED
SQLState	08W29
ODBC State	08001
Probable cause

The engine has denied permission to start/stop a database.


Result set not allowed from within an atomic compound statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Result set not allowed from within an atomic compound statement

Item	Value
SQLCode	-222
Constant	SQLE_RESULT_NOT_ALLOWED
SQLState	3BW02
ODBC State	S1000
Probable cause

A SELECT statement with no INTO clause or a RESULT CURSOR statement are not allowed within an atomic compound statement.


Right truncation of string data
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Right truncation of string data

Item	Value
SQLCode	-638
Constant	SQLE_STRING_RIGHT_TRUNCATION
SQLState	22001
ODBC State	22001
Probable cause

Non-space characters were truncated upon the assignment of string data.


ROLLBACK TO SAVEPOINT not allowed
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

ROLLBACK TO SAVEPOINT not allowed

Item	Value
SQLCode	-221
Constant	SQLE_ROLLBACK_NOT_ALLOWED
SQLState	3B002
ODBC State	S1000
Probable cause

A ROLLBACK TO SAVEPOINT within an atomic operation is not allowed to a savepoint established before the atomic operation.


Row has been updated since last time read
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Row has been updated since last time read

Item	Value
SQLCode	104
Constant	SQLE_ROW_UPDATED_WARNING
SQLState	01W04
ODBC State	(handled by ODBC driver)
Probable cause

A FETCH has retrieved a row from a cursor declared as a SCROLL cursor, and the row was previously fetched from the same cursor, and one or more columns in the row has been updated since the previous fetch. Note that 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 cancelled
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Row has changed since last read -- operation cancelled

Item	Value
SQLCode	-208
Constant	SQLE_ROW_UPDATED_SINCE_READ
SQLState	22W02
ODBC State	(handled by ODBC driver)
Probable cause

You have done a UPDATE (positioned) or DELETE (positioned) on a cursor declared as a SCROLL cursor, and the row you are changing has been updated since you read it. This prevents the 'lost update' problem.


Run time SQL error  --  %1
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Run time SQL error  --  %1

Item	Value
SQLCode	-300
Constant	SQLE_ERROR
SQLState	40000
ODBC State	S1000
Parameter 1	Identification of the error.
Probable cause

This error indicates an internal database error, and should be reported to SQL Anywhere technical support.


Savepoint '%1' not found
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Savepoint '%1' not found

Item	Value
SQLCode	-220
Constant	SQLE_SAVEPOINT_NOTFOUND
SQLState	3B001
ODBC State	S1000
Parameter 1	Name of savepoint.
Probable cause

You attempted to rollback to a savepoint that does not exist.


Savepoints require a rollback log
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Savepoints require a rollback log

Item	Value
SQLCode	-213
Constant	SQLE_SAVEPOINTS_REQUIRE_UNDO
SQLState	3BW01
ODBC State	S1000
Probable cause

You cannot use savepoints when the database engine is running in bulk mode without a rollback log.


SELECT lists in UNION do not match in length
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

SELECT lists in UNION do not match in length

Item	Value
SQLCode	-153
Constant	SQLE_INVALID_UNION
SQLState	53026
ODBC State	37000
Probable cause

You have specified a UNION but the SELECT statements involved in the union do not have the same number of columns in the select list.


SELECT returns more than one row
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

SELECT returns more than one row

Item	Value
SQLCode	-185
Constant	SQLE_TOO_MANY_RECORDS
SQLState	21000
ODBC State	S1000
Probable cause

An Embedded SELECT statement that does not use a cursor returns more than one result.


Server/database engine version mismatch
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Server/database engine version mismatch

Item	Value
SQLCode	-232
Constant	SQLE_SERVER_ENGINE_MISMATCH
SQLState	08W20
ODBC State	08001
Probable cause

Your version of the database server software is not compatible with your version of the database engine.


Specified database is invalid
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Specified database is invalid

Item	Value
SQLCode	-84
Constant	SQLE_INVALID_DATABASE
SQLState	08W11
ODBC State	08001
Probable cause

The database engine was started but the specified database file is invalid.  The engine is stopped.


Specified database not found
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Specified database not found

Item	Value
SQLCode	-83
Constant	SQLE_DATABASE_NOT_FOUND
SQLState	08W10
ODBC State	08001
Probable cause

The database engine or multiuser client was started but was unable to find the specified database or server name. The database file cannot be opened or the specified server cannot be found on the network. The database engine or client is stopped.


SQL Anywhere HLI internal error
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

SQL Anywhere HLI internal error

Item	Value
SQLCode	-406
Constant	SQLE_HLI_INTERNAL
SQLState	WI007
ODBC State	WI007
Probable cause

This is a SQL Anywhere internal error and should be reported to Watcom.


SQL statement error
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

SQL statement error

Item	Value
SQLCode	-132
Constant	SQLE_STATEMENT_ERROR
SQLState	26501
ODBC State	S1000
Probable cause

The statement identifier (generated by PREPARE) passed to the database for a further operation is invalid.


Sqlpp/dblib version mismatch
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Sqlpp/dblib version mismatch

Item	Value
SQLCode	-230
Constant	SQLE_PP_DBLIB_MISMATCH
SQLState	08W18
ODBC 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.


Standard logons are not permitted
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Standard logons are not permitted

Item	Value
SQLCode	-206
Constant	SQLE_INVALID_INTEGRATED_LOGON
SQLState	28W03
ODBC State	28000
Probable cause

The engine logon type switch (gl) is set to INTEGRATED logon type, and the user has attempted a standard logon.


Statement cannot be executed
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Statement cannot be executed

Item	Value
SQLCode	111
Constant	SQLE_CANNOT_EXECUTE_STMT
SQLState	01W08
ODBC State	(handled by ODBC driver)
Probable cause

You have 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 interrupted by user
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Statement interrupted by user

Item	Value
SQLCode	-299
Constant	SQLE_INTERRUPTED
SQLState	57014
ODBC State	S1000
Probable cause

The user has aborted 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 cancelled. If the statement is a data definition command (for example CREATE TABLE), the command will be cancelled, but the COMMIT that was done as a side effect will not be cancelled.


Subquery allowed only one select list item
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Subquery allowed only one select list item

Item	Value
SQLCode	-151
Constant	SQLE_SUBQUERY_SELECT_LIST
SQLState	53023
ODBC State	37000
Probable cause

You have 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 result
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Subquery cannot return more than one result

Item	Value
SQLCode	-186
Constant	SQLE_SUBQUERY_RESULT_NOT_UNIQUE
SQLState	21W01
ODBC State	37000
Probable cause

The result of a subquery contains more than one row. If the subquery is in the WHERE clause, you might be able to use IN.


Subscription to '%1' for '%2' already exists
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Subscription to '%1' for '%2' already exists

Item	Value
SQLCode	-282
Constant	SQLE_SUBSCRIPTION_NOT_UNIQUE
SQLState	5RW03
ODBC State	S0002
Parameter 1	Name of the publication.
Parameter 2	Name of the user.
Probable cause

You have tried to create a subscription that already exists.


Subscription to '%1' for '%2' not found
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Subscription to '%1' for '%2' not found

Item	Value
SQLCode	-283
Constant	SQLE_SUBSCRIPTION_NOT_FOUND
SQLState	5RW04
ODBC State	S0002
Parameter 1	Name of the publication.
Parameter 2	Name of the user.
Probable cause

You have tried to drop, start, or synchronize a subscription that does not exist.


Syntax error near '%1'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Syntax error near '%1'

Item	Value
SQLCode	-131
Constant	SQLE_SYNTAX_ERROR
SQLState	42W04
ODBC State	37000
Parameter 1	The word or symbol where the syntax error has been detected.
Probable cause

The database engine cannot understand the command you are trying to execute. If you have used a keyword (such as DATE) for a column name, try enclosing the keyword in quotation marks ("DATE").


Table '%1' has no primary key
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Table '%1' has no primary key

Item	Value
SQLCode	-118
Constant	SQLE_NO_PRIMARY_KEY
SQLState	55008
ODBC State	23000
Parameter 1	Name of the table that does not have a primary key.
Probable cause

You have attempted to add a foreign key referring to a table that does not have a primary key. You will need to add a primary key to the named table.


Table '%1' has publications
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Table '%1' has publications

Item	Value
SQLCode	-281
Constant	SQLE_TABLE_HAS_PUBLICATIONS
SQLState	5RW02
ODBC State	S0002
Parameter 1	Name of the publication that has publications.
Probable cause

You have attempted to drop a table that has publications defined.


Table '%1' is in an outer join cycle
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Table '%1' is in an outer join cycle

Item	Value
SQLCode	-136
Constant	SQLE_OUTER_JOIN_CYCLE
SQLState	52W14
ODBC State	37000
Parameter 1	Name of a table in the cycle.
Probable cause

You have specified outer joins that create a cycle of tables.


Table '%1' not found
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Table '%1' not found

Item	Value
SQLCode	-141
Constant	SQLE_TABLE_NOT_FOUND
SQLState	42W33
ODBC State	42000
Parameter 1	Name of the table that could not be found.
Probable cause

You have misspelled the name of a table, or you have connected with a different user ID and forgotten to 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
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Table '%1' requires a unique correlation name

Item	Value
SQLCode	-137
Constant	SQLE_CORRELATION_NAME_NEEDED
SQLState	52W15
ODBC State	37000
Parameter 1	Name of the table that needs a unique correlation name.
Probable cause

You have 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
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Table already has a primary key

Item	Value
SQLCode	-112
Constant	SQLE_EXISTING_PRIMARY_KEY
SQLState	55013
ODBC State	23000
Probable cause

You have tried 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
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Table cannot have two primary keys

Item	Value
SQLCode	-126
Constant	SQLE_PRIMARY_KEY_TWICE
SQLState	52W05
ODBC State	23000
Probable cause

You have specified the primary key twice in a CREATE TABLE command.


Table in use
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Table in use

Item	Value
SQLCode	-214
Constant	SQLE_TABLE_IN_USE
SQLState	42W21
ODBC State	40001
Probable cause

You have attempted to ALTER or DROP a table that is being used by other active users of the database.


Table must be empty
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Table must be empty

Item	Value
SQLCode	-116
Constant	SQLE_TABLE_MUST_BE_EMPTY
SQLState	55W02
ODBC State	S1000
Probable cause

You have attempted to modify a table, and SQL Anywhere can only perform the change if there are no rows in the table.


Terminated by user -- transaction rolled back
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Terminated by user -- transaction rolled back

Item	Value
SQLCode	-302
Constant	SQLE_TERMINATED_BY_USER
SQLState	40W02
ODBC State	S1000
Probable cause

The user has aborted a command while the database was executing. A ROLLBACK WORK command has been automatically executed. This will happen when the engine is running in bulk mode and the user aborts an INSERT, UPDATE, or DELETE operation.


The selected database is currently inactive
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

The selected database is currently inactive

Item	Value
SQLCode	-74
Constant	SQLE_DATABASE_NOT_ACTIVE
SQLState	08W30
ODBC State	08001
Probable cause

The selected database is in an inactive state. This state occurs during database initialization and shutdown.


The supplied buffer was too small to hold all requested query results
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

The supplied buffer was too small to hold all requested query results

Item	Value
SQLCode	400
Constant	SQLE_HLI_MORE_DATA_AVAILABLE
SQLState	01WH1
ODBC State	(handled by ODBC driver)
Probable cause

You attempted to get a query result set using the WSQL HLI function wsqlquerytomem. The buffer supplied by the calling application was too small to contain the entire query.  The buffer will contain as many rows of the result set as possible, and the cursor will be positioned on the next row of the result set.


There are still active database connections
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

There are still active database connections

Item	Value
SQLCode	-109
Constant	SQLE_STILL_ACTIVE_CONNECTIONS
SQLState	08W06
ODBC State	S1000
Probable cause

An application has requested SQL Anywhere to shutdown the database using the db_stop() function when there are still active connections to the database.


There is already a variable named '%1'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

There is already a variable named '%1'

Item	Value
SQLCode	-261
Constant	SQLE_VARIABLE_EXISTS
SQLState	42W15
ODBC State	37000
Probable cause

You have tried to CREATE a variable with the name of another variable that already exists.


There is more than one way to join '%1' to '%2'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

There is more than one way to join '%1' to '%2'

Item	Value
SQLCode	-147
Constant	SQLE_AMBIGUOUS_JOIN
SQLState	52W08
ODBC State	37000
Parameter 1	Name of first table that cannot be joined.
Parameter 2	Name of second table that cannot be joined.
Probable cause

There are two or more foreign keys relating the two tables and you are attempting to KEY JOIN the two tables. Either there are two foreign keys from the first table to the second table, or 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'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

There is no way to join '%1' to '%2'

Item	Value
SQLCode	-146
Constant	SQLE_CANNOT_JOIN
SQLState	53W04
ODBC State	37000
Parameter 1	Name of first table that cannot be joined.
Parameter 2	Name of second table that cannot be joined.
Probable cause

You 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; or you have attempted a NATURAL JOIN between two tables and the tables have no common column names.


Too many columns in table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Too many columns in table

Item	Value
SQLCode	-616
Constant	SQLE_TOO_MANY_COLUMNS_IN_TABLE
SQLState	52W20
ODBC State	S1000
Probable cause

A CREATE TABLE or ALTER TABLE statement attempted to add a column to a table, but the resulting number of columns in the table would exceed the limit for the current database page size.


Too many connections to database
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Too many connections to database

Item	Value
SQLCode	-102
Constant	SQLE_TOO_MANY_CONNECTIONS
SQLState	08W03
ODBC State	08004
Probable cause

If you are running the multiuser client, you have exceeded the number of computers allowed to connect to the server by your license agreement. Otherwise, the single user DOS engine is limited to 2 connections, and the Windows engine is restricted to 10 connections.


Too many parameters to this external procedure call
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Too many parameters to this external procedure call

Item	Value
SQLCode	-625
Constant	SQLE_TOO_MANY_PARAMETERS
SQLState	WW010
ODBC State	S1000
Probable cause

This is a Windows 32-bit specific error. There is a maximum of 256 parameters to an external function call.


Transact-SQL feature not supported
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Transact-SQL feature not supported

Item	Value
SQLCode	-611
Constant	SQLE_TSQL_FEATURE_NOT_SUPPORTED
SQLState	0AW02
ODBC State	37000
Probable cause

An attempt was made to use a feature of Transact-SQL that is not supported.


Transaction log backup page only partially full
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Transaction log backup page only partially full

Item	Value
SQLCode	110
Constant	SQLE_BACKUP_PAGE_INCOMPLETE
SQLState	01W10
ODBC State	(handled by ODBC driver)
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
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Transaction log was truncated

Item	Value
SQLCode	-244
Constant	SQLE_LOG_TRUNCATED
SQLState	WB005
ODBC State	S1000
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 independant backup during that operation.


Trigger '%1' not found
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Trigger '%1' not found

Item	Value
SQLCode	-268
Constant	SQLE_TRIGGER_NOT_FOUND
SQLState	52W10
ODBC State	S0002
Parameter 1	Name of the trigger that could not be found.
Probable cause

You have misspelled the name of a trigger, or you have connected with a different userid and forgotten to qualify a trigger name with a user name.


Trigger definition conflicts with existing triggers
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Trigger definition conflicts with existing triggers

Item	Value
SQLCode	-271
Constant	SQLE_TRIGGER_DEFN_CONFLICT
SQLState	52W11
ODBC State	S0001
Probable cause

A trigger definition could not be created because it conflicts with an existing trigger definition.  A trigger with the same name may already exist.


Triggers and procedures not supported in runtime engine
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Triggers and procedures not supported in runtime engine

Item	Value
SQLCode	-275
Constant	SQLE_PROCEDURES_NOT_IN_DESKTOP
SQLState	0AW04
ODBC State	S1000
Probable cause

You have 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 desktop engine.  Triggers and stored procedures are not supported in the runtime engine.  You must be running the full engine to use these features.


Unable to delete database file
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Unable to delete database file

Item	Value
SQLCode	-243
Constant	SQLE_BACKUP_UNABLE_TO_DELETE_FILE
SQLState	WB004
ODBC State	S1000
Probable cause

The specified file could not be deleted.  The filename should not be the same as any database file that is currently in use.


Unable to find in index '%1' for table '%2'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Unable to find in index '%1' for table '%2'

Item	Value
SQLCode	-189
Constant	SQLE_NOT_FOUND_IN_INDEX
SQLState	WI005
ODBC State	S1000
Parameter 1	Name of invalid index.
Parameter 2	Name of table containing the invalid index.
Probable cause

This is a SQL Anywhere internal error and should be reported to SQL Anywhere technical support. You should be able to work around the error by dropping and recreating the index.


Unable to start database engine
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Unable to start database engine

Item	Value
SQLCode	-80
Constant	SQLE_UNABLE_TO_START_ENGINE
SQLState	08W07
ODBC State	08001
Probable cause

It was not possible to start the database engine or multiuser client. Either there is not enough memory to run the database engine, or the executable cannot be found.


Unable to start specified database
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Unable to start specified database

Item	Value
SQLCode	-82
Constant	SQLE_UNABLE_TO_START_DATABASE
SQLState	08W09
ODBC State	08001
Probable cause

The database engine or multiuser client was started but was unable to find the specified database or server name.  No specific reason is known.


Unknown backup operation
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Unknown backup operation

Item	Value
SQLCode	-240
Constant	SQLE_UNKNOWN_BACKUP_OPERATION
SQLState	WB001
ODBC State	S1000
Probable cause

An invalid backup command operation was specified in a call to db_backup.


Unknown function '%1'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Unknown function '%1'

Item	Value
SQLCode	-148
Constant	SQLE_UNKNOWN_FUNC
SQLState	42W05
ODBC State	37000
Parameter 1	Function name that is not a database function.
Probable cause

You have misspelled the name of a database function (such as MAXIMUM instead of MAX) in a query definition or in a query column name.


Unterminated C string
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Unterminated C string

Item	Value
SQLCode	-634
Constant	SQLE_UNTERMINATED_C_STR
SQLState	22024
ODBC 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
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Update operation attempted on a read-only cursor

Item	Value
SQLCode	-633
Constant	SQLE_READ_ONLY_CURSOR
SQLState	42W30
ODBC State	42030
Probable cause

An update operation has been attempted on a cursor that was explicitly declared as read-only.


Update operation attempted on non-updatable query
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Update operation attempted on non-updatable query

Item	Value
SQLCode	-192
Constant	SQLE_NON_UPDATEABLE_VIEW
SQLState	42W31
ODBC State	42031
Probable cause

You have attempted an insert, update, or delete operation on a query that is implictly read-only. An updatable query may not contain DISTINCT, GROUP BY, HAVING, or UNION, nor may it contain aggregate functions or involve a join. If the query references a view then the query expression that defines the view must itself be updatable.


User '%1' already has grant permission
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

User '%1' already has grant permission

Item	Value
SQLCode	-120
Constant	SQLE_ALREADY_HAS_GRANT_PERMS
SQLState	42W01
ODBC State	37000
Parameter 1	Name of the userid that already has GRANT permission.
Probable cause

The SQL GRANT command is attempting to give a user GRANT OPTION and that user already has GRANT OPTION.


User '%1' already has membership in group '%2'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

User '%1' already has membership in group '%2'

Item	Value
SQLCode	-312
Constant	SQLE_ALREADY_HAS_GROUP_MEMBERSHIP
SQLState	42W34
ODBC State	37000
Parameter 1	Name of the userid that already has membership.
Parameter 2	Name of the group.
Probable cause

The SQL GRANT command is attempting to give a membership in a group to user that already has such membership.


User '%1' has the row in '%2' locked
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

User '%1' has the row in '%2' locked

Item	Value
SQLCode	-210
Constant	SQLE_LOCKED
SQLState	42W18
ODBC State	40001
Parameter 1	Name of another user.
Parameter 2	Table which generates the error.
Probable cause

You have attempted to read or write a row and it is locked by another user.  Note that this error will only be received if the database option BLOCKING is set to OFF.  Otherwise, the requesting transaction will block until the row lock is released.


User '%1' is already the publisher for this database
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

User '%1' is already the publisher for this database

Item	Value
SQLCode	-284
Constant	SQLE_ONLY_ONE_PUBLISHER
SQLState	5RW05
ODBC State	S0002
Parameter 1	Name of the publisher.
Probable cause

You have tried to GRANT PUBLISH to a userid, when a publisher already exists.


User '%1' is not a remote user for this database
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

User '%1' is not a remote user for this database

Item	Value
SQLCode	-285
Constant	SQLE_NOT_REMOTE_USER
SQLState	5RW06
ODBC State	S0002
Parameter 1	Name of user.
Probable cause

You have tried 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
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

User '%1' is not a user group

Item	Value
SQLCode	-123
Constant	SQLE_NOT_A_GROUP
SQLState	42W03
ODBC State	37000
Parameter 1	Name of user you thought was a group.
Probable cause

You have tried to add a member to group, but the group specified has not been granted the GROUP special privilege.


User message %1 already exists
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

User message %1 already exists

Item	Value
SQLCode	-610
Constant	SQLE_MESSAGE_ALREADY_EXISTS
SQLState	52W16
ODBC State	23000
Probable cause

The message with this error number already exists in SYSUSERMESSAGES.


User message %1 not found
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

User message %1 not found

Item	Value
SQLCode	-612
Constant	SQLE_MESSAGE_NOT_FOUND
SQLState	52W17
ODBC State	S0002
Parameter 1	Message number.
Probable cause

The message with this error number does not exist in SYSUSERMESSAGES.


User-defined exception signalled
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

User-defined exception signalled

Item	Value
SQLCode	-297
Constant	SQLE_USER_DEFINED_EXCEPTION
SQLState	99999
ODBC State	S1000
Probable cause

A stored procedure or trigger signalled a user-defined exception. This error state is reserved for use within stored procedures or triggers which contain exception handlers, as a way of signalling an exception which can be guaranteed to not have been caused by the database engine.


User-defined type %1 not found
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

User-defined type %1 not found

Item	Value
SQLCode	-613
Constant	SQLE_USER_TYPE_NOT_FOUND
SQLState	52W18
ODBC State	S0002
Parameter 1	Name of the user-defined type.
Probable cause

The user-defined type with this name does not exist in SYSUSERTYPE.


Userid '%1' does not exist
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Userid '%1' does not exist

Item	Value
SQLCode	-140
Constant	SQLE_UNKNOWN_USERID
SQLState	08004
ODBC State	28000
Parameter 1	Name of the userid that could not be found.
Probable cause

The specified userid does not exist.


Using temporary table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Using temporary table

Item	Value
SQLCode	102
Constant	SQLE_TEMPORARY_TABLE
SQLState	01W02
ODBC State	(handled by ODBC driver)
Probable cause

A temporary table has been created in order to satisfy the query. It can only occur on an OPEN statement.


Value %1 out of range for destination
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Value %1 out of range for destination

Item	Value
SQLCode	-158
Constant	SQLE_OVERFLOW_ERROR
SQLState	22003
ODBC State	22003
Parameter 1	The value that caused the overflow.
Probable cause

A value has been supplied to the database or retrieved from the database 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
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Value for column '%1' in table '%2' has changed

Item	Value
SQLCode	106
Constant	SQLE_COLUMN_VALUE_CHANGED
SQLState	01W06
ODBC State	(handled by ODBC driver)
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
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Value truncated

Item	Value
SQLCode	101
Constant	SQLE_TRUNCATED
SQLState	01004
ODBC State	01004
Probable cause

You have tried to insert, update, or select a value in the database which is too large to fit in the destination. This warning is also produced if you do a fetch, and the host variable or SQLDA variable is not large enough to receive the value.


Variable '%1' not found
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Variable '%1' not found

Item	Value
SQLCode	-260
Constant	SQLE_VARIABLE_NOT_FOUND
SQLState	42W14
ODBC State	37000
Probable cause

You have tried to DROP or SET the value of a SQL variable that was not created or was previously dropped.


Warning
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Warning

Item	Value
SQLCode	200
Constant	SQLE_WARNING
SQLState	01000
ODBC State	(handled by ODBC driver)
Probable cause

A warning has occurred.  The warning message will indicate the condition that caused the warning.


WITH CHECK OPTION violated for view '%1'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

WITH CHECK OPTION violated for view '%1'

Item	Value
SQLCode	-632
Constant	SQLE_WITH_CHECK_OPTION_VIOLATION
SQLState	44000
ODBC State	44000
Parameter 1	View where check option violated
Probable cause

A value in the row(s) being inserted or modified fell outside the range of the view


Wrong number of parameters to function '%1'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Wrong number of parameters to function '%1'

Item	Value
SQLCode	-154
Constant	SQLE_WRONG_PARAMETER_COUNT
SQLState	37505
ODBC State	37000
Parameter 1	Name of the function.
Probable cause

You have supplied an incorrect number of parameters to a database function.


Wrong number of values for INSERT
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Wrong number of values for INSERT

Item	Value
SQLCode	-207
Constant	SQLE_WRONG_NUM_OF_INSERT_COLS
SQLState	53002
ODBC State	37000
Probable cause

The number of values you are trying to insert does not match the number of columns specified in the INSERT command, or the number of columns in the table if no columns are specified.


Wrong number of variables in FETCH
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Alphabetic list of error messages

Wrong number of variables in FETCH

Item	Value
SQLCode	-264
Constant	SQLE_WRONG_NUM_OF_FETCH_VARIABLES
SQLState	42W26
ODBC State	37000
Probable cause

The number of variables specified in the FETCH statement does not match the number of select list items.


Internal errors (assertion failed)
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 42. SQL Anywhere Database Error Messages

Internal errors (assertion failed)

The SQL Anywhere engine has many internal checks that have been designed to detect possible database corruption as soon as possible. If the database engine 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 SQL 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 the chapter "Backup and Recovery").


SQL Preprocessor Error Messages
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

About this chapter

This chapter presents a list of all SQL preprocessor errors and warnings.

 SQLPP errors

 SQLPP warnings


SQLPP errors
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

 subscript value %ld too large

 combined pointer and arrays not supported for hosttypes

 only one dimensional arrays supported for char type

 VARCHAR type must have a length

 arrays of VARCHAR not supported

 VARCHAR host variables cannot be pointers

 initializer not allowed on VARCHAR host variable

 FIXCHAR type must have a length

 arrays of FIXCHAR not supported

 arrays of int not supported

 precision must be specified for decimal type

 arrays of decimal not allowed

 Unknown hostvar type

 invalid integer

 '%s' host variable must be a C string type

 '%s' symbol already defined

 invalid type for sql statement variable

 Cannot find include file '%s'

 host variable '%s' is unknown

 indicator variable '%s' is unknown

 invalid type for indicator variable '%s'

 invalid host variable type on '%s'

 host variable '%s' has two different definitions

 statement '%s' not previously prepared

 cursor '%s' not previously declared

 unknown statement '%s'

 host variables not allowed for this cursor

 host variables specified twice - on declare and open

 must specify a host list or using clause on %s

 no INTO clause on SELECT statement

 incorrect Embedded SQL syntax

 missing ending quote of string

 token too long

 '%s' host variable must be an integer type


subscript value %ld too large
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

subscript value %ld too large

Item	Value
Code	2601
Probable cause

You have attempted to index a host variable that is an array with a value too large for the array.


combined pointer and arrays not supported for hosttypes
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

combined pointer and arrays not supported for hosttypes

Item	Value
Code	2602
Probable cause

You have used an array of pointers as a host variable. This is not legal.


only one dimensional arrays supported for char type
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

only one dimensional arrays supported for char type

Item	Value
Code	2603
Probable cause

You have used an array of arrays of character as a host variable. This is not a legal host variable type.


VARCHAR type must have a length
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

VARCHAR type must have a length

Item	Value
Code	2604
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 VARCHAR not supported
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

arrays of VARCHAR not supported

Item	Value
Code	2605
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.


VARCHAR host variables cannot be pointers
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

VARCHAR host variables cannot be pointers

Item	Value
Code	2606
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.


initializer not allowed on VARCHAR host variable
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

initializer not allowed on VARCHAR host variable

Item	Value
Code	2607
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.


FIXCHAR type must have a length
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

FIXCHAR type must have a length

Item	Value
Code	2608
Probable cause

You have used the DECL_FIXCHAR macro to declare a host variable of type FIXCHAR but have not specified a length.


arrays of FIXCHAR not supported
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

arrays of FIXCHAR not supported

Item	Value
Code	2609
Probable cause

You have attempted to declare a host variable as an array of FIXCHAR. This is not a legal host variable type.


arrays of int not supported
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

arrays of int not supported

Item	Value
Code	2610
Probable cause

You have attempted to declare a host variable as an array of ints. This is not a legal host variable type.


precision must be specified for decimal type
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

precision must be specified for decimal type

Item	Value
Code	2611
Probable cause

You must specify the precision when declaring a packed decimal host variable using the DECL_DECIMAL macro. The scale is optional.


arrays of decimal not allowed
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

arrays of decimal not allowed

Item	Value
Code	2612
Probable cause

You have attempted to declare a host variable as an array of DECIMAL. This is not a legal host variable type.


Unknown hostvar type
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

Unknown hostvar type

Item	Value
Code	2613
Probable cause

You declared a host variable of a type not understood by the SQL preprocessor.


invalid integer
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

invalid integer

Item	Value
Code	2614
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.


'%s' host variable must be a C string type
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

'%s' host variable must be a C string type

Item	Value
Code	2615
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.


'%s' symbol already defined
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

'%s' symbol already defined

Item	Value
Code	2617
Probable cause

You defined a host variable twice with different definitions.


invalid type for sql statement variable
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

invalid type for sql statement variable

Item	Value
Code	2618
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.


Cannot find include file '%s'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

Cannot find include file '%s'

Item	Value
Code	2619
Probable cause

The specified include file was not found. Note that the preprocessor will use the INCLUDE environment variable to search for include files.


host variable '%s' is unknown
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

host variable '%s' is unknown

Item	Value
Code	2620
Probable cause

You have used a host variable in a statement and that host variable has not been declared in a declare section.


indicator variable '%s' is unknown
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

indicator variable '%s' is unknown

Item	Value
Code	2621
Probable cause

You have used a indicator variable in a statement and that indicator variable has not been declared in a declare section.


invalid type for indicator variable '%s'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

invalid type for indicator variable '%s'

Item	Value
Code	2622
Probable cause

Indicator variables must be of type short int. You have used a variable of a different type as an indicator variable.


invalid host variable type on '%s'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

invalid host variable type on '%s'

Item	Value
Code	2623
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.


host variable '%s' has two different definitions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

host variable '%s' has two different definitions

Item	Value
Code	2625
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.


statement '%s' not previously prepared
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

statement '%s' not previously prepared

Item	Value
Code	2626
Probable cause

An embedded SQL statement name has been used (EXECUTEd) without first being PREPAREd.


cursor '%s' not previously declared
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

cursor '%s' not previously declared

Item	Value
Code	2627
Probable cause

An embedded SQL cursor name has been used (in a FETCH, OPEN, CLOSE etc.) without first being DECLAREd.


unknown statement '%s'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

unknown statement '%s'

Item	Value
Code	2628
Probable cause

You attempted to drop an embedded SQL statement that doesn't exist.


host variables not allowed for this cursor
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

host variables not allowed for this cursor

Item	Value
Code	2629
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
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

host variables specified twice - on declare and open

Item	Value
Code	2630
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.


must specify a host list or using clause on %s
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

must specify a host list or using clause on %s

Item	Value
Code	2631
Probable cause

The specified statement requires host variables to be specified either in a host variable list or from an SQLDA.


no INTO clause on SELECT statement
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

no INTO clause on SELECT statement

Item	Value
Code	2633
Probable cause

You specified an embedded static SELECT statement but you did not specify an INTO clause for the results.


incorrect Embedded SQL syntax
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

incorrect Embedded SQL syntax

Item	Value
Code	2636
Probable cause

An embedded SQL specific statement (OPEN, DECLARE, FETCH etc.) has a syntax error.


missing ending quote of string
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

missing ending quote of string

Item	Value
Code	2637
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.


token too long
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

token too long

Item	Value
Code	2639
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.


'%s' host variable must be an integer type
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP errors

'%s' host variable must be an integer type

Item	Value
Code	2640
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.


SQLPP warnings
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP warnings

 Into clause not allowed on declare cursor - ignored

 unrecognized SQL syntax

 unknown sql function '%s'

 wrong number of parms to sql function '%s'

 static statement names will not work properly if used by 2 threads


Into clause not allowed on declare cursor - ignored
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP warnings

Into clause not allowed on declare cursor - ignored

Item	Value
Code	2660
Probable cause

You have specified an into clause on a SELECT statement in a declare cursor. Note that the into clause will be ignored.


unrecognized SQL syntax
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP warnings

unrecognized SQL syntax

Item	Value
Code	2661
Probable cause

You have used a SQL statement that will probably cause a syntax error when the statement is sent to the database engine.


unknown sql function '%s'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP warnings

unknown sql function '%s'

Item	Value
Code	2662
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.


wrong number of parms to sql function '%s'
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP warnings

wrong number of parms to sql function '%s'

Item	Value
Code	2663
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.


static statement names will not work properly if used by 2 threads
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 43. SQL Preprocessor Error Messages

SQLPP warnings

static statement names will not work properly if used by 2 threads

Item	Value
Code	2664
Probable cause

You have used a static statement name and preprocessed with the -r reentrancy 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.


Differences from Other SQL Dialects
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 44. Differences from Other SQL Dialects

About this chapter

SQL Anywhere conforms to the ANSI SQL89 standard but has many additional features defined in IBM's DB2 and SAA specification, and in ANSI SQL/92.

This chapter describes those features of SQL Anywhere that are not commonly found in other SQL implementations.

 SQL Anywhere features


SQL Anywhere features
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 44. Differences from Other SQL Dialects

SQL Anywhere features

The following SQL Anywhere features 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

SQL 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 "Watcom-SQL Functions" for a description of these.

Integrity

SQL 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. SQL 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

SQL Anywhere allows automatic joins between tables. In addition to the NATURAL and OUTER join operators supported in other implementations, SQL Anywhere allows KEY joins between tables based on foreign key relationships. This reduces the complexity of the WHERE clause when performing joins.

Updates

SQL 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

SQL 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 SQL Anywhere but not valid in most other SQL implementations.

SELECT      emp_lname,

         emp_birthdate,

         (   SELECT skill

            FROM department

            WHERE emp_id = employee.emp_ID

            AND dept_id = 200 )

FROM employee

Additional functions

SQL Anywhere supports several functions not in the ANSI SQL definition. See "Watcom-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.


SQL Anywhere Limitations
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 45. SQL Anywhere Limitations

About this chapter

This chapter describes the limitations on size and number of objects in SQL Anywhere databases.

 Size and number limitations


Size and number limitations
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 45. SQL Anywhere Limitations

Size and number limitations

The following table lists the limitations on size and number of objects in SQL Anywhere database. The memory and disk drive of the microcomputer are more limiting factors in most cases.

Item	Limitation
Database size	2 GB per file, 12 files per database *
Number of tables per database	32,767
Number of tables referenced per transaction	No limit
Table size	2 GB—must be in one file *
Number of columns per table	999 (using 4K pages)
Number of rows per table	Limited by table size
Row size	Limited by table size
Number of rows per database	Limited by file size
Field size	2 GB
Number of indexes	32,767 per table
Maximum index entry size	No limit
User-created indexes for the table can be stored separately from the table. The 2 GB limit for table size does not apply to Windows NT databases using the NTFS file system. For this platform only, the maximum table size is the largest file size allowed by the operating system.


SQL Anywhere Keywords
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 46. SQL Anywhere Keywords

About this chapter

This chapter lists SQL keywords reserved by SQL Anywhere. If any of these keywords are to be used as an identifier they should be enclosed in quotation marks.

A number of these keywords are not used in the current implementation of SQL Anywhere but are reserved for future enhancements.

The keywords are listed alphabetically.

 Alphabetical list of keywords


Alphabetical list of keywords
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 46. SQL Anywhere Keywords

Alphabetical list of keywords

If you use a keyword (also called a reserved word) in an identifier you must enclose it in double quotes when referencing it in a SQL statement. Many, but not all, of the words that appear in SQL statements are keywords.

add	all	alter	and
any	as	asc	begin
between	binary	break	by
call	cascade	cast	char
char_convert	character	check	checkpoint
close	comment	commit	connect
constraint	continue	convert	create
cross	current	cursor	date
dba	dbspace	deallocate	dec
decimal	declare	default	delete
desc	distinct	do	double
drop	else	elseif	encrypted
end	endif	escape	exception
exec	execute	exists	fetch
first	float	for	foreign
from	full	goto	grant
group	having	holdlock	identified
if	in	index	inner
inout	insert	instead	int
integer	into	is	isolation
join	key	left	like
lock	long	match	membership
message	mode	modify	named
natural	noholdlock	not	null
numeric	of	off	on
open	option	options	or
order	others	out	outer
passthrough	precision	prepare	primary
print	privileges	proc	procedure
raiserror	readtext	real	reference
references	release	remote	rename
resource	restrict	return	revoke
right	rollback	save	savepoint
schedule	select	set	share
smallint	some	sqlcode	sqlstate
start	stop	subtrans	subtransaction
synchronize	syntax_error	table	temporary
then	time	tinyint	to
tran	trigger	truncate	tsequal
union	unique	unknown	update
user	using	validate	values
varbinary	varchar	variable	varying
view	when	where	while
with	work	writetext
If you are using Embedded SQL, the database library function sql_needs_quotes can be used to determine if a string requires quotation marks to make it an identifier because it is a reserved word or contains invalid identifier characters.


SQL Anywhere System Procedures and Functions
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 47. SQL Anywhere System Procedures and Functions

About this chapter

This chapter documents the system-supplied catalog stored procedures in SQL Anywhere databases, used to retrieve system information.  The chapter also documents system-supplied extended procedures, including procedures for sending e-mail messages on a MAPI e-mail system.

 System procedure overview

 Catalog stored procedures

 System extended stored procedures


System procedure overview
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 47. SQL Anywhere System Procedures and Functions

System procedure overview

SQL Anywhere includes the following kinds of system procedures:

♦	Catalog stored procedures, for displaying system information in tabular form.

♦	Extended stored procedures for MAPI e-mail support and other functions.

♦	Transact-SQL system and catalog procedures.

  For a list of these system procedures see "SQL Server system and catalog procedures".

♦	System functions that are implemented as stored procedures.

  For information see "System functions".

This chapter documents the catalog stored procedures and the extended stored procedures for MAPI e-mail support and other external functions.


Catalog stored procedures
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 47. SQL Anywhere System Procedures and Functions

Catalog stored procedures

The following catalog procedures return result sets displaying database engine, database, and connection properties in tabular form.

sa_db_info( [ database-id ] )   Returns a single row containing the Number, Alias, File, ConnCount, PageSize, and LogName for the specified database.

sa_conn_info( [ connection-id ] )   Returns the Number, Name, Userid, DBNumber, LastReqTime, ProcessTime, Port, ReqType, CommLink, NodeAddr, LastIdle, CurrTaskSw, BlockedOn, and UncmtOps properties for each connection. If no connection-id is supplied, information for all current connections to databases on the server is returned.

sa_db_properties( [ database-id ] )   Returns the database id number and the Number, PropNum, PropName, PropDescription, and Value, for each property returned by the sa_db_info system procedure.

sa_eng_properties()   Returns the PropNum, PropName, PropDescription, and Value for each available engine property.

  For a listing of available engine properties, see "System functions".

sa_conn_properties( [ connection-id ] )   Returns the connection id as Number, and the PropNum, PropName, PropDescription, and Value for each available connection property.

  For a listing of available connection properties, see "System functions". These system procedures are owned by the "DBO" user ID. The PUBLIC group has EXECUTE permission on these procedures.


System extended stored procedures
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 47. SQL Anywhere System Procedures and Functions

System extended stored procedures

A set of system extended procedures are included into SQL Anywhere databases. These procedures are owned by the DBO user ID that owns the Transact-SQL-compatibility system views.

The following sections describe each of the stored procedures.

 MAPI system extended stored procedures

 Other system extended stored procedures


MAPI system extended stored procedures
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 47. SQL Anywhere System Procedures and Functions

System extended stored procedures

MAPI system extended stored procedures

SQL Anywhere includes a set of three system procedures for sending electronic mail using Microsoft's Messaging API standard (MAPI). These system procedures are implemented as Extended Stored Procedures: each of the procedures calls a function in an external DLL.

In order to use the MAPI stored procedures, a MAPI e-mail system must be accessible from the database server machine.

The MAPI stored procedures are:

♦	xp_startmail   Starts a mail session in a specified mail account by logging on the MAPI message system

♦	xp_sendmail   Sends a mail message to specified users

♦	xp_stopmail   Closes the 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 MAPI system procedures are discussed in the following sections.

 xp_startmail system procedure

 xp_sendmail system procedure

 xp_stopmail system procedure


xp_startmail system procedure
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 47. SQL Anywhere System Procedures and Functions

System extended stored procedures

MAPI system extended stored procedures

xp_startmail system procedure

Purpose

To start an e-mail session.

Syntax

[ [ variable = ] CALL ] xp_startmail (

...     [ mail_user = mail-login-name ]

...     [, mail_password = mail-password ]

...     )

Usage

Anywhere.

Authorization

None.

Description

xp_startmail is a system stored procedure that starts an e-mail session. It is implemented as a user-defined function.

xp_startmail returns an integer. The return value is zero if the login is successful, and non-zero otherwise.

The mail-login-name and mail-password values are strings containing the MAPI login name and password to be used in the mail session.

If you are using Microsoft Exchange, the mail_user argument is an Exchange profile name, and you should not include a password in the procedure call.

Return codes

The xp_startmail system procedure uses the following return codes:

Return code	Meaning
0	Success
2	Failure


xp_sendmail system procedure
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 47. SQL Anywhere System Procedures and Functions

System extended stored procedures

MAPI system extended stored procedures

xp_sendmail system procedure

Purpose

To send an e-mail message.

Syntax

[ [ variable = ] CALL ] xp_sendmail (

...  [ recipient = mail-address ]

...  [, cc_recipient = mail-address ]

...  [, bcc_recipient = mail-address ]

...  [, "message" = message-body ]

...  [, include_file = file-name ]

... )

Usage

Anywhere.

Authorization

Must have executed xp_startmail to start an e-mail session.

Description

xp_sendmail is a system stored procedure that sends an e-mail message once a session has been started using :name_startmail:ename.. It is implemented as a user-defined function.

xp_sendmail returns an integer. The return value is zero if the message is successfully sent, and non-zero otherwise.

The argument values are strings. The message parameter name requires double quotes around it as MESSAGE is a keyword.

Return codes

The xp_sendmail system procedure uses the following return codes:

Return code	Meaning
0	Success
5	Failure (general)
11	Ambiguous recipient
12	Attachment not found
13	Disk full
14	Insufficient memory
15	Invalid session
16	Text too large
17	Too many files
18	Too many recipients
19	Unknown recipient


xp_stopmail system procedure
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 47. SQL Anywhere System Procedures and Functions

System extended stored procedures

MAPI system extended stored procedures

xp_stopmail system procedure

Purpose

To close an e-mail session.

Syntax

[ variable = ] [ CALL ] xp_stopmail ()

Usage

Anywhere.

Authorization

None.

Description

xp_stopmail is a system stored procedure that starts an e-mail session. It is implemented as a user-defined function.

xp_stopmail returns an integer. The return value is zero if the mail session is successfully closed, and non-zero otherwise.

Return codes

The xp_stopmail system procedure uses the following return codes:

Return code	Meaning
0	Success
3	Failure


Other system extended stored procedures
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 47. SQL Anywhere System Procedures and Functions

System extended stored procedures

Other system extended stored procedures

The other system extended stored procedures included are:

♦	xp_cmdshell   Executes a system command.

♦	xp_sprintf   Takes as input a format string and a set of string arguments, and returns a string.

♦	xp_scanf   Takes as input a string and a format string, and returns a set of strings.

♦	xp_msver   Takes as input one of a set of predefined strings, and returns a string containing version information.

The following sections provide more detail on each of these procedures.

 xp_cmdshell system procedure

 xp_msver system function

 xp_sprintf system procedure

 xp_scanf system procedure


xp_cmdshell system procedure
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 47. SQL Anywhere System Procedures and Functions

System extended stored procedures

Other system extended stored procedures

xp_cmdshell system procedure

Purpose

To carry out an operating system command from a procedure.

Syntax

[ variable = CALL ] xp_cmdshell ( string )

Usage

Anywhere.

Authorization

None.

Description

xp_cmdshell is a system stored procedure that executes a system command and then returns control to the calling environment.


xp_msver system function
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 47. SQL Anywhere System Procedures and Functions

System extended stored procedures

Other system extended stored procedures

xp_msver system function

Purpose

To retrieve version and name information about the database engine or server.

Syntax

xp_msver ( string )

The string must be one of the following, enclosed in string delimiters.

Argument	Description
ProductName	The name of the product (Sybase SQL Anywhere)
ProductVersion	The version number, followed by the build number. The format is as follows: 5.5.02 (1200)
CompanyName	Returns the following string: Sybase 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
Returns

String containing information appropriate to the argument.

Usage

Anywhere.

Authorization

None.

Description

xp_msver returns product, company, version, and other information.


xp_sprintf system procedure
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 47. SQL Anywhere System Procedures and Functions

System extended stored procedures

Other system extended stored procedures

xp_sprintf system procedure

Purpose

To build up a string from a format string and a set of input strings.

Syntax

[ variable = CALL ] xp_sprintf ( out-string,

...     format-string

...     [ input-string, ... ] )

Usage

Anywhere.

Authorization

None.

Description

xp_sprintf is a system stored procedure that 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.


xp_scanf system procedure
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 47. SQL Anywhere System Procedures and Functions

System extended stored procedures

Other system extended stored procedures

xp_scanf system procedure

Purpose

To extract substrings from an input string and a format string.

Syntax

[ variable = CALL ] xp_scanf ( in-string,

...     format-string

...     [ output-string, ... ] )

Usage

Anywhere.

Authorization

None.

Description

xp_scanf is a system stored procedure that extracts substrings from an input string and a format string. The format-string can contain up to fifty string placeholders (%s). The value of these placeholders in the are filled in by the output-string arguments.

All arguments must be strings of less than 254 characters.


SQL Anywhere System Tables
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

About this chapter

The structure of every SQL Anywhere database is described in a number of system tables.

The Entity-Relationship diagram on the next page shows all the system tables and the foreign keys connecting the system tables.

The system tables are owned by the SYS user ID. The contents of these tables can only be changed by the database system. Thus, 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.

Following a diagram of the system tables, the tables are listed alphabetically.

 System tables diagram

 Alphabetical list of system tables


System tables diagram
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

System tables diagram

The SQL Anywhere system tables are shown in the following diagram. Foreign key relations between tables are indicated by arrows: the arrow leads from the foreign table to the primary table.


Alphabetical list of system tables
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

This section contains descriptions of each of the system tables. The system tables are described via the CREATE TABLE commands used to create them. They serve as good examples of how tables are created in SQL. Following the CREATE TABLE command, each column is briefly described.

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

 SYSARTICLE system table

 SYSARTICLECOL system table

 SYSCOLLATE system table

 SYSCOLPERM system table

 SYSCOLUMN system table

 SYSDOMAIN system table

 SYSFILE system table

 SYSFKCOL system table

 SYSFOREIGNKEY system table

 SYSGROUP system table

 SYSINDEX system table

 SYSINFO system table

 SYSIXCOL system table

 SYSOPTION system table

 SYSPROCEDURE system table

 SYSPROCPARM system table

 SYSPROCPERM system table

 SYSPUBLICATION system table

 SYSREMOTEUSER system table

 SYSSUBSCRIPTION system table

 SYSTABLE system table

 SYSTABLEPERM system table

 SYSTRIGGER system table

 SYSUSERMESSAGES system table

 SYSUSERPERM system table

 SYSUSERTYPE system table


DUMMY system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

DUMMY system table

CREATE TABLE SYS.DUMMY (

   dummy_col      INT NOT NULL

)

The DUMMY table is provided as a 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

dummy_col   This column is not used. It is present because a table cannot be created with no columns.


SYSARTICLE system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSARTICLE system table

CREATE TABLE SYS.SYSARTICLE (

   publication_id   SMALLINT NOT NULL,

   table_id   SMALLINT NOT NULL,

   where_expr   LONG VARCHAR,

   subscribe_by_expr   LONG VARCHAR,

   PRIMARY KEY ( publication_id, table_id ),

   FOREIGN KEY REFERENCES SYS.SYSPUBLICATION,

   FOREIGN KEY REFERENCES SYS.SYSTABLE

)

Each row of SYSARTICLE describes an article in a SQL Remote 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.


SYSARTICLECOL system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSARTICLECOL system table

CREATE TABLE SYS.SYSARTICLECOL (

   publication_id   SMALLINT NOT NULL,

   table_id   SMALLINT NOT NULL,

   column_id   SMALLINT NOT NULL,

   PRIMARY KEY (publication_id, table_id, column_id),

   FOREIGN KEY REFERENCES SYS.SYSARTICLE,

   FOREIGN KEY REFERENCES SYS.SYSCOLUMN

)

Each row identifies a column in an article, identifying the column, the table it is in, and the publication it is part of.

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.


SYSCOLLATE system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSCOLLATE system table

CREATE TABLE SYS.SYSCOLLATION (

   collation_id   SMALLINT NOT NULL,

   collation_name   CHAR(128) NOT NULL,

   collation_label   CHAR(10) NOT NULL,

   collation_order   BINARY(256) NOT NULL,

   PRIMARY KEY ( collation_id )

)

This table contains the collation sequences available to SQL Anywhere. There is no way to modify the contents of this table.

collation_id   A unique number identifying the collation sequence. The collation sequence with collation_id equal 2 is the sequence used in previous versions of SQL Anywhere, and is the default when a database is created with DBINIT.

collation_name   The name of the collation sequence.

collation_label   A string identifying each of the available collation sequences. The collation sequence to be used is selected when the database is created by specifying the collation label with the -z option.

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.


SYSCOLPERM system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSCOLPERM system table

CREATE TABLE SYS.SYSCOLPERM (

   table_id   SMALLINT NOT NULL,

   grantee   SMALLINT NOT NULL,

   grantor   SMALLINT NOT NULL,

   column_id   SMALLINT NOT NULL,

   privilege_type   SMALLINT NOT NULL,

   is_grantable   CHAR( 1 ) NOT NULL,

   PRIMARY KEY ( table_id, grantee,

   grantor, column_id, privilege_type ),

   FOREIGN KEY grantee ( grantee ) REFERENCES

   SYS.SYSUSERPERM ( user_id ),

   FOREIGN KEY grantor ( grantor ) REFERENCES

   SYS.SYSUSERPERM ( user_id ),

   FOREIGN KEY REFERENCES SYS.SYSCOLUMN

)

The GRANT command can give UPDATE permission to individual columns in a table. Each column with UPDATE 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 given UPDATE permission on the column. If the grantee is the user number for the special PUBLIC user ID, the UPDATE permission is given to all user IDs.

grantor   The user number of the user ID granting the permission.

column_id   This column number, together with the table_id, identifies the column for which UPDATE permission has been granted.

privilege_type   The number in this column indicates the kind of column permission (REFERENCES, SELECT or UPDATE).

is_grantable   (Y/N). Indicates if the permission on the column was granted by the grantor to the grantee WITH GRANT OPTION.


SYSCOLUMN system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSCOLUMN system table

CREATE TABLE SYS.SYSCOLUMN (

   table_id   SMALLINT NOT NULL,

   column_id   SMALLINT NOT NULL,

   pkey   CHAR(1) NOT NULL,

   domain_id   SMALLINT NOT NULL,

   nulls   CHAR(1) NOT NULL,

   width   SMALLINT NOT NULL,

   scale   SMALLINT NOT NULL,

   estimate   INT NOT NULL,

   column_name   CHAR(128) NOT NULL,

   remarks   LONG VARCHAR,

   "default"      LONG VARCHAR,

   "check"   LONG VARCHAR,

   user_type      SMALLINT,

   format_str   CHAR(128),

   PRIMARY KEY ( table_id, column_id ),

   FOREIGN KEY REFERENCES SYS.SYSTABLE,

   FOREIGN KEY REFERENCES SYS.SYSDOMAIN

)

Each column in every table or view is described by one row in SYSCOLUMN.

table_id   The table number 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   Identify the data type for the column by the data type number listed in the SYSDOMAIN table.

nulls (Y/N)   Indicate whether the NULL value is allowed in this column.

width   This column contains the length of string columns, the precision of numeric columns, and the number of bytes of storage for all other data types.

scale   The number of digits after the decimal point for numeric data type columns, and zero for all other data types.

estimate   A self-tuning parameter for the optimizer. SQL Anywhere will learn from previous queries by adjusting guesses that are made by the optimizer.

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.

check.   Any CHECK condition defined on the column.

user_type   If the column is defined on a user-defined data type, the data type is held here.

format_str   Currently unused.


SYSDOMAIN system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSDOMAIN system table

CREATE TABLE SYS.SYSDOMAIN (

   domain_id      SMALLINT NOT NULL,

   domain_name   CHAR(128) NOT NULL,

   type_id   SMALLINT,

   precision      SMALLINT,

   PRIMARY KEY ( domain_id )

)

Each of the predefined data types (sometimes called domains) in SQL Anywhere is assigned a unique number. The SYSDOMAIN table is provided for informational purposes to show the association between these numbers and the appropriate data type. This table is never changed by SQL Anywhere.

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.


SYSFILE system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSFILE system table

CREATE TABLE SYS.SYSFILE (

   file_id   SMALLINT NOT NULL,

   file_name   CHAR(80) NOT NULL,

   dbspace_name   CHAR(128) NOT NULL,

   PRIMARY KEY ( file_id )

)

Every database consists of one or more operating system files. Each file 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 database name is stored when a database is created. This name is for informational purposes only.

dbspace_name   Every file has a dbspace name that is unique. It is used in the CREATE TABLE command.


SYSFKCOL system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSFKCOL system table

CREATE TABLE SYS.SYSFKCOL (

   foreign_table_id   SMALLINT NOT NULL,

   foreign_key_id   SMALLINT NOT NULL,

   foreign_column_id   SMALLINT NOT NULL,

   primary_column_id   SMALLINT NOT NULL,

   PRIMARY KEY ( foreign_table_id,

   foreign_key_id, foreign_column_id ),

   FOREIGN KEY REFERENCES SYS.SYSFOREIGNKEY,

   FOREIGN KEY ( foreign_table_id,

   foreign_column_id ) REFERENCES

   SYS.SYSCOLUMN ( table_id, column_id )

)

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, and the table number for the primary table can be obtained from that row.

foreign_column_id   This column number, together with the foreign_table_id, identify the foreign column description in SYSCOLUMN.

primary_column_id   This column number, together with the primary_table_id obtained from SYSFOREIGNKEY, identify the primary column description in SYSCOLUMN.


SYSFOREIGNKEY system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSFOREIGNKEY system table

CREATE TABLE SYS.SYSFOREIGNKEY (

   foreign_table_id   SMALLINT NOT NULL,

   foreign_key_id   SMALLINT NOT NULL,

   primary_table_id   SMALLINT NOT NULL,

   root   INT NOT NULL,

   check_on_commit   CHAR(1) NOT NULL,

   nulls   CHAR(1) NOT NULL,

   role   CHAR(128) NOT NULL,

   remarks   LONG VARCHAR,

   PRIMARY KEY ( foreign_table_id, foreign_key_id ),

   UNIQUE ( role, foreign_table_id ),

   FOREIGN KEY foreign_table ( foreign_table_id )

   REFERENCES SYS.SYSTABLE ( table_id ),

   FOREIGN KEY primary_table ( primary_table_id )

   REFERENCES SYS.SYSTABLE ( table_id )

)

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   Foreign keys are stored in the database as B-trees. The root identifies the location of the root of the B-tree in the database file.

nulls   (Y/N)   Indicate 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.

check_on_commit  (Y/N)   Indicate whether INSERT and UPDATE commands should wait until the next COMMIT command 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.

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.


SYSGROUP system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSGROUP system table

CREATE TABLE SYS.SYSGROUP (

   group_id   SMALLINT NOT NULL,

   group_member   SMALLINT NOT NULL,

   PRIMARY KEY ( group_id, group_member ),

   FOREIGN KEY group_id ( group_id ) REFERENCES

   SYS.SYSUSERPERM ( user_id ),

   FOREIGN KEY group_member ( group_member )

   REFERENCES SYS.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 group.

group_member   The user number of a member.


SYSINDEX system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSINDEX system table

CREATE TABLE SYS.SYSINDEX (

   table_id   SMALLINT NOT NULL,

   index_id   SMALLINT NOT NULL,

   root   INT NOT NULL,

   file_id   SMALLINT NOT NULL,

   "unique" CHAR(1) NOT NULL,

   creator   SMALLINT NOT NULL,

   index_name   CHAR(128) NOT NULL,

   remarks   LONG VARCHAR,

   PRIMARY KEY ( table_id, index_id ),

   UNIQUE ( index_name, creator ),

   FOREIGN KEY REFERENCES SYS.SYSTABLE,

   FOREIGN KEY REFERENCES SYS.SYSFILE,

   FOREIGN KEY ( creator ) REFERENCES

   SYS.SYSUSERPERM ( user_id )

)

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   The table number uniquely identifies the table to which this index applies.

index_id   Each index for one particular table is assigned a unique index number.

root   Indexes are stored in the database as B-trees. The root identifies the location of the root of the B-tree in the database file.

file_id   The index is completely contained in the file with this file_id (see SYSFILE). In the current implementation of SQL Anywhere, this file is always the same as the file containing the table.

unique   Indicate 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. In the current implementation of SQL Anywhere, this user is always the same as the creator of the table identified by table_id.

index_name   The name of the index. A user ID cannot have two indexes with the same name.

remarks   A comment string.


SYSINFO system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSINFO system table

CREATE TABLE SYS.SYSINFO (

   page_size   SMALLINT NOT NULL,

   encryption   CHAR(1) NOT NULL,

   blank_padding   CHAR(1) NOT NULL,

   case_sensitivity   CHAR(1) NOT NULL,

   default_collation   CHAR(10) NOT NULL,

   database_version   SMALLINT NOT NULL

)

This table indicates the database characteristics as defined when the database was created using DBINIT. It always contains only one row.

page_size   The page size specified to DBINIT. The default value is 1024.

encryption   The value "Y" or "N" depending on whether the -e switch was used with DBINIT.

blank_padding   The value "Y" or "N" depending on whether the database was created to use blank padding for string comparisons in the database ( -b switch was used with DBINIT).

case_sensitivity   The value "Y" or "N" depending on whether the -c switch was used with DBINIT. Case sensitivity affects value comparisons, but not table and column name comparisons. For example, if case sensitivity is enabled, the system catalog names such as SYSCATALOG must be specified in uppercase since that is how the name was spelled when it was created.

default_collation   A string corresponding to the collation_label in SYSCOLLATE corresponding to the collation sequence specified with DBINIT. The default value corresponds to the multilingual collation sequence (code page 850), which was the default prior to Watcom SQL 3.2. 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. As newer versions of SQL Anywhere become available, new features may require that the format of the database file change. The version number allows SQL Anywhere software to determine if this database was created with a newer version of the software and thus cannot be understood by the software in use.


SYSIXCOL system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSIXCOL system table

CREATE TABLE SYS.SYSIXCOL (

   table_id   SMALLINT NOT NULL,

   index_id   SMALLINT NOT NULL,

   sequence   SMALLINT NOT NULL,

   column_id   SMALLINT NOT NULL,

   "order" CHAR(1) NOT NULL,

   PRIMARY KEY ( table_id, index_id, sequence )

   FOREIGN KEY REFERENCES SYS.SYSINDEX,

   FOREIGN KEY REFERENCES SYS.SYSCOLUMN

)

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 in SYSCOLUMN.

order (A/D)   Indicate whether this column in the index is kept in ascending or descending order.


SYSOPTION system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSOPTION system table

CREATE TABLE SYS.SYSOPTION (

   user_id   SMALLINT NOT NULL,

   "option" CHAR(128) NOT NULL,

   "setting" CHAR(80) NOT NULL,

   PRIMARY KEY ( user_id, "option" ),

   FOREIGN KEY REFERENCES SYS.SYSUSERPERM

)

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.


SYSPROCEDURE system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSPROCEDURE system table

CREATE TABLE SYS.SYSPROCEDURE (

   proc_id   SMALLINT NOT NULL,

   creator   SMALLINT NOT NULL,

   proc_name   CHAR(128) NOT NULL,

   proc_defn   LONG VARCHAR,

   remarks   LONG VARCHAR,

   replicate   CHAR(1) NOT NULL,

   PRIMARY KEY ( proc_id ),

   UNIQUE ( proc_name, creator ),

   FOREIGN KEY ( creator ) REFERENCES

   SYS.SYSUSERPERM ( user_id )

)

Each procedure in the database is described by one row in SYSPROCEDURE.

proc_id   Each procedure is assigned a unique number (the procedure number) that 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 used to create the procedure.

remarks   A comment string.

replicate   Holds a Y if the procedure is a primary data source in a Replication Server installation, or an N if not.


SYSPROCPARM system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSPROCPARM system table

CREATE TABLE SYS.SYSPROCPARM (

   proc_id   SMALLINT NOT NULL,

   parm_id   SMALLINT NOT NULL,

   parm_type   SMALLINT NOT NULL,

   parm_mode_in   CHAR(1) NOT NULL,

   parm_mode_out   CHAR(1) NOT NULL,

   domain_id   SMALLINT NOT NULL,

   width   SMALLINT NOT NULL,

   scale   SMALLINT NOT NULL,

   parm_name   CHAR(128) NOT NULL,

   remarks   LONG VARCHAR,

   "default" LONG VARCHAR,

   PRIMARY KEY ( proc_id, parm_id ),

   FOREIGN KEY REFERENCES SYS.SYSPROCEDURE,

   FOREIGN KEY REFERENCES SYS.SYSDOMAIN

)

Each parameter to a procedure in the database is described by one row in SYSPROCEDURE.

proc_id   The procedure number 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.

parm_type   The type of parameter will be one of the following:

♦	0-variable   normal parameter

♦	1-result   result variable - used with procedure that return result sets

♦	2-SQLSTATE   SQLSTATE error value

♦	3-SQLCODE   SQLCODE error value

parm_mode_in (Y/N)   Indicate whether this parameter supplies a value to the procedure (IN or INOUT parameters).

parm_mode_out   (Y/N)   Indicate whether this parameter returns a value from the procedure (OUT or INOUT parameters).

domain_id   Identify the data type for the parameter by the data type number listed in the SYSDOMAIN table.

width   This column contains the length of string parameters, the precision of numeric parameters, and the number of bytes of storage for all other data types.

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 parameter.

remarks   A comment string.

default   The default value for the parameter, held as a string.


SYSPROCPERM system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSPROCPERM system table

CREATE TABLE SYS.SYSPROCPERM (

   proc_id   SMALLINT NOT NULL,

   grantee   SMALLINT NOT NULL,

   PRIMARY KEY ( proc_id, grantee )

   FOREIGN KEY ( grantee ) REFERENCES

   SYS.SYSUSERPERM ( user_id ),

   FOREIGN KEY REFERENCES SYS.SYSPROCEDURE

)

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
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSPUBLICATION system table

CREATE TABLE SYS.SYSPUBLICATION (

   publication_id   SMALLINT NOT NULL,

   creator   SMALLINT NOT NULL,

   publication_name   CHAR(128) NOT NULL,

   remarks   LONG VARCHAR,

   PRIMARY KEY ( publication_id ),

   FOREIGN KEY ( creator )

   REFERENCES SYS.SYSUSERPERM (user_id )

)

Each row describes a SQL Remote publication.

publication_id   A unique identifying number for the publication.

creator   The owner of the publication.

publication_name   The name of the publication, which must be a valid identifier.

remarks   Descriptive comments.


SYSREMOTEUSER system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSREMOTEUSER system table

CREATE TABLE SYS.SYSREMOTEUSER (

   user_id            SMALLINT NOT NULL,

   consolidate         CHAR(1) NOT NULL,

   type_id            SMALLINT NOT NULL,

   address            LONG VARCHAR NOT NULL,

   frequency         CHAR(!) NOT NULL,

   send_time         TIME,

   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,

   PRIMARY KEY (user_id),

   FOREIGN KEY REFERENCES SYS.SYSUSERPERM

)

Each row describes a userid with REMOTE permissions (a subscriber), together with the status of SQL Remote messages sent to and from that user.

user_id   The user ID of the user with REMOTE permissions.

consolidate   The column contains either an R to indicate a user granted REMOTE permissions, or a C to indicate a user granted CONSOLIDATE permissions.

type_id   Identifies which of the of the message systems supported by SQL Remote is to be 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.

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.


SYSSUBSCRIPTION system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSSUBSCRIPTION system table

CREATE TABLE SYS.SYSSUBSCRIPTION (

   publication_id   SMALLINT NOT NULL,

   user_id   SMALLINT NOT NULL,

   subscribe_by   CHAR(128) NOT NULL,

   created   NUMERIC(20,0) NOT NULL,

   started   NUMERIC(20,0),

   PRIMARY KEY (publication_id, user_id, subscribe_by),

   FOREIGN KEY REFERENCES SYS.SYSPUBLICATION,

   FOREIGN KEY REFERENCES SYS.SYSREMOTEUSER

);

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 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.


SYSTABLE system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSTABLE system table

CREATE TABLE SYS.SYSTABLE (

   table_id   SMALLINT NOT NULL,

   file_id   SMALLINT NOT NULL,

   count   INTEGER NOT NULL,

   first_page   INT NOT NULL,

   last_page   INT NOT NULL,

   primary_root   INT NOT NULL,

   creator   SMALLINT NOT NULL,

   table_name   CHAR(128) NOT NULL,

   table_type   CHAR(10) NOT NULL,

   view_def   LONG VARCHAR,

   remarks   LONG VARCHAR,

   replicate   CHAR(1) NOT NULL,

   PRIMARY KEY ( table_id ),

   UNIQUE ( table_name, creator ),

   FOREIGN KEY ( creator ) REFERENCES

   SYS.SYSUSERPERM ( user_id ),

   FOREIGN KEY REFERENCES SYS.SYSFILE

)

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) that is the primary key for SYSTABLE.

file_id   The file number indicates which database file contains the table. The file_id is a FOREIGN KEY for SYSFILE.

count   The number of rows in the table is updated during each successful CHECKPOINT. This number is used by SQL Anywhere when optimizing database access. The count is always 0 for a view.

first_page   Each SQL Anywhere database is divided into a number of fixed size pages. This value identifies the first page containing 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 containing information for this table. The last_page is always 0 for a view.

primary_root   Primary keys are stored in the database as B-trees. The primary_root locates the root of the B-tree for the primary key for the table. It will be 0 for a view and for a table with no primary key.

creator   This user number identifies the owner of the table or view. The name of the user can be found by looking in SYSUSERPERM.

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 will be "BASE" for base tables and "VIEW" for views. It will be "GBL TEMP" for global temporary tables and "LCL TEMP" for local temporary tables.

view_def   For a view, this column contains the create view command used to create the view. For a table, this column will contain any CHECK constraints for the table.

remarks   A comment string.

replicate   Holds a Y if the table is a primary data source in a Replication Server installation, or an N if not.


SYSTABLEPERM system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSTABLEPERM system table

CREATE TABLE SYS.SYSTABLEPERM (

   stable_id   SMALLINT NOT NULL,

   grantee   SMALLINT NOT NULL,

   grantor   SMALLINT NOT NULL,

   ttable_id   SMALLINT NOT NULL,

   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,

   PRIMARY KEY ( stable_id, grantee, grantor ),

   FOREIGN KEY ( stable_id )

   REFERENCES SYS.SYSTABLE ( table_id ),

   FOREIGN KEY future ( ttable_id )

   REFERENCES SYS.SYSTABLE ( table_id ),

   FOREIGN KEY grantee ( grantee ) REFERENCES

   SYS.SYSUSERPERM ( user_id ),

   FOREIGN KEY grantor ( grantor )

   REFERENCES SYS.SYSUSERPERM ( user_id )

)

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. In addition, the grantee can grant the same permission to another user

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 SQL Anywhere, this table number is always the same as stable_id.

selectauth (Y/N/G)   Indicate whether SELECT permission has been granted.

insertauth (Y/N/G)   Indicate whether INSERT permission has been granted.

deleteauth (Y/N/G)   Indicate whether DELETE permission has been granted.

updateauth (Y/N/G)   Indicate whether UPDATE permission has been granted for all columns in the table. (Only UPDATE permission can be given on individual columns. All other permissions are for all columns in a 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)   Indicate whether ALTER permission has been granted.

referenceauth (Y/N/G)   Indicate whether REFERENCE permission has been granted.


SYSTRIGGER system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSTRIGGER system table

CREATE TABLE SYS.SYSTRIGGER (

trigger_id SMALLINT NOT NULL,

   table_id   SMALLINT NOT NULL,

   event   CHAR(1) NOT NULL,

   trigger_time   CHAR(1) NOT NULL,

   trigger_order   SMALLINT,

   foreign_table_id   SMALLINT,

   foreign_key_id   SMALLINT,

   referential_action   CHAR(1),

   trigger_name   CHAR(128),

   trigger_defn   LONG VARCHAR NOT NULL,

   remarks   LONG VARCHAR,

   PRIMARY KEY ( trigger_id ),

   UNIQUE ( trigger_name ),

   UNIQUE ( table_id, event,

   trigger_time, trigger_order ),

   UNIQUE ( table_id, foreign_table_id,

   foreign_key_id, event ),

   FOREIGN KEY REFERENCES SYS.SYSTABLE,

   FOREIGN KEY REFERENCES SYS.SYSFOREIGNKEY

)

Each trigger in the database is described by one row in SYSTRIGGER. The table also contains triggers automatically created by the database 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) that 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.

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 foreign table number identifies 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 identifies 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 used to create the trigger.

remarks   A comment string.


SYSUSERMESSAGES system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSUSERMESSAGES system table

CREATE TABLE SYS.SYSUSERMESSAGES (

   error   INT NOT NULL,

   uid   SMALLINT NOT NULL,

   description   VARCHAR(255) NOT NULL,

   langid   SMALLINT NOT NULL,

   UNIQUE ( error,langid )

)

Each row holds a user-defined message for an error condition.

error   A unique identifying number for the error condition.

uid   The user ID defining the message.

description   The message corresponding to the error condition.

langid   Reserved.


SYSUSERPERM system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSUSERPERM system table

CREATE TABLE SYS.SYSUSERPERM (

   user_id   SMALLINT NOT NULL,

   user_name   CHAR(128) NOT NULL UNIQUE,

   password   CHAR(128),

   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,

   PRIMARY KEY ( user_id )

)

DBA permissions required—SYSUSERPERM contains passwords, and so DBA permissions are required to SELECT from the table.

Each row of SYSUSERPERM describes one user ID.

user_id   Each new user ID is assigned a unique number (the user number) that is the primary key for SYSUSERPERM.

user_name      A string containing the name for the user ID. Each userid must have a unique name.

password   The password for the user ID. The password contains the NULL value for the special userids SYS and PUBLIC, preventing anyone from connecting to these user IDs.

resourceauth (Y/N)   Indicate whether the user has RESOURCE authority. Resource authority is required to create tables.

dbaauth (Y/N)   Indicate 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.

publishauth (Y/N)   Indicate whether the user has the SQL Remote publisher authority.

remotedbaauth (Y/N)   Indicate whether the user has the SQL Remote remote DBA authority.

scheduleauth (Y/N)   Indicate whether the user has SCHEDULE authority. This is currently not used by SQL Anywhere.

user_group (Y/N)   ndicate 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.

There is no way to connect to the SYS or PUBLIC user IDs.


SYSUSERTYPE system table
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 48. SQL Anywhere System Tables

Alphabetical list of system tables

SYSUSERTYPE system table

CREATE TABLE SYS.SYSUSERTYPE (

   type_id   SMALLINT NOT NULL,

   creator   SMALLINT NOT NULL,

   domain_id   SMALLINT NOT NULL,

   nulls   CHAR(1) NOT NULL,

   width   SMALLINT NOT NULL,

   scale   SMALLINT NOT NULL,

   type_name   CHAR(128) NOT NULL,

   "default" LONG VARCHAR NULL,

   "check" LONG VARCHAR NULL,

   format_str   CHAR(128),

   UNIQUE ( type_name ),

   PRIMARY KEY ( type_id ),

   FOREIGN KEY ( creator )

   REFERENCES SYS.SYSUSERPERM ( user_id ),

   FOREIGN KEY REFERENCES SYS.SYSDOMAIN

)

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 owner of the data type.

domain_id   Identifies the data type for the column by the data type number listed in the SYSDOMAIN table.

nulls   A Y indicates that the user-defined data type does allow nulls. A N indicates that the data type does not allow nulls.

width   This column contains the length of string columns, the precision of numeric columns, and the number of bytes of storage for all other data types.

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, which must be a valid identifier.

"default"   The default value for the data type.

"check"   The CHECK condition for the data type.

format_str   Currently unused.


SQL Anywhere System Views
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 49. SQL Anywhere System Views

About this chapter

This chapter lists predefined views for the SQL Anywhere system tables.

The system tables described in the chapter "SQL Anywhere System Tables" use numbers to identify tables, user IDs, and so forth. While this is efficient for internal use by SQL Anywhere, 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.

The definitions for the system views are included with their descriptions. Some of these definitions are complicated, but need not be understood to use the views. They serve as good examples of what can be accomplished using the SELECT command and views.

The views are listed alphabetically

 Alphabetical list of views


Alphabetical list of views
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 49. SQL Anywhere System Views

Alphabetical list of views

Each of the views is described by its CREATE statement.

 SYS.SYSCATALOG

 SYS.SYSCOLAUTH

 SYS.SYSCOLUMNS

 SYS.SYSFOREIGNKEYS

 SYS.SYSGROUPS

 SYS.SYSINDEXES

 SYS.SYSOPTIONS

 SYS.SYSPROCPARMS

 SYS.SYSREMOTEUSERS

 SYS.SYSTABAUTH

 SYS.SYSTRIGGERS

 SYS.SYSUSERAUTH

 SYS.SYSUSERLIST

 SYS.SYSUSEROPTIONS

 SYS.SYSUSERPERMS

 SYS.SYSVIEWS


SYS.SYSCATALOG
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 49. SQL Anywhere System Views

Alphabetical list of views

SYS.SYSCATALOG

CREATE VIEW SYS.SYSCATALOG ( creator,

   tname, dbspacename, tabletype, ncols,

   primary_key, "check", remarks )

AS

SELECT ( SELECT user_name FROM SYS.SYSUSERPERM

            WHERE user_id = SYSTABLE.creator ),

      table_name,

      ( SELECT dbspace_name from SYS.SYSFILE

            WHERE file_id = SYSTABLE.file_id ),

      IF table_type='BASE' THEN 'TABLE'

         ELSE table_type ENDIF,

      ( SELECT count(*) FROM SYS.SYSCOLUMN

         WHERE table_id = SYSTABLE.table_id ),

      IF primary_root = 0 THEN 'N' ELSE 'Y' ENDIF,

      IF table_type <> VIEW' THEN view_def ENDIF,

      remarks

FROM SYS.SYSTABLE

Lists all the tables and views from SYSTABLE in a readable format.


SYS.SYSCOLAUTH
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 49. SQL Anywhere System Views

Alphabetical list of views

SYS.SYSCOLAUTH

CREATE VIEW SYS.SYSCOLAUTH ( grantor, grantee,

   creator, tname, colname )

AS

SELECT ( SELECT user_name FROM SYS.SYSUSERPERM

         WHERE user_id = SYSCOLPERM.grantor ),

      ( SELECT user_name FROM SYS.SYSUSERPERM

         WHERE user_id = SYSCOLPERM.grantee ),

      ( SELECT user_name

         FROM SYS.SYSUSERPERM == SYS.SYSTABLE

         WHERE table_id = SYSCOLPERM.table_id ),

      ( SELECT table_name FROM SYS.SYSTABLE

         WHERE table_id = SYSCOLPERM.table_id ),

      ( SELECT column_name FROM SYS.SYSCOLUMN

         WHERE table_id = SYSCOLPERM.table_id

         AND column_id = SYSCOLPERM.column_id )

FROM SYS.SYSCOLPERM

Presents column update permission information in SYSCOLPERM in a more readable format.


SYS.SYSCOLUMNS
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 49. SQL Anywhere System Views

Alphabetical list of views

SYS.SYSCOLUMNS

CREATE VIEW SYS.SYSCOLUMNS ( creator, cname, tname,

coltype, nulls, length, syslength,

in_primary_key, "colno", default_value, remarks )

AS

SELECT ( SELECT user_name FROM SYS.SYSUSERPERM

         WHERE user_id = SYSTABLE.creator ),

      column_name, table_name,

      ( SELECT domain_name FROM SYS.SYSDOMAIN

         WHERE domain_id = SYSCOLUMN.domain_id ),

      nulls, width, scale, pkey, column_id,

      "default", SYSCOLUMN.remarks

FROM SYS.SYSCOLUMN == SYS.SYSTABLE

Presents a readable version of the table SYSCOLUMN. (Note the S at the end of the view name that distinguishes it from the SYSCOLUMN table.)


SYS.SYSFOREIGNKEYS
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 49. SQL Anywhere System Views

Alphabetical list of views

SYS.SYSFOREIGNKEYS

CREATE VIEW SYS.SYSFOREIGNKEYS ( foreign_creator,

   foreign_tname, primary_creator,

   primary_tname, role, columns )

AS

SELECT ( SELECT user_name FROM

         SYS.SYSUSERPERM == SYS.SYSTABLE

         WHERE table_id = foreign_table_id ),

      ( SELECT table_name FROM SYS.SYSTABLE

         WHERE table_id = foreign_table_id ),

      ( SELECT user_name

         FROM SYS.SYSUSERPERM == SYS.SYSTABLE

         WHERE table_id = primary_table_id ),

      ( SELECT table_name FROM SYS.SYSTABLE

         WHERE table_id = primary_table_id ), role,

      ( SELECT list( string( FK.column_name,

         ' IS ', PK.column_name ) )

         FROM SYS.SYSFKCOL KEY JOIN

         SYS.SYSCOLUMN FK, SYS.SYSCOLUMN PK

         WHERE foreign_table_id =

         SYSFOREIGNKEY.foreign_table_id

         AND foreign_key_id =

                SYSFOREIGNKEY.foreign_key_id

         AND PK.table_id =

               SYSFOREIGNKEY.primary_table_id

         AND PK.column_id =

               SYSFKCOL.primary_column_id )

FROM SYS.SYSFOREIGNKEY

Presents foreign key information from SYSFOREIGNKEY and SYSFKCOL in a more readable format.


SYS.SYSGROUPS
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 49. SQL Anywhere System Views

Alphabetical list of views

SYS.SYSGROUPS

CREATE VIEW SYS.SYSGROUPS ( group_name, member_name )

AS

SELECT g.user_name, u.user_name

FROM   SYS.SYSGROUP,

      SYS.SYSUSERPERM g,

      SYS.SYSUSERPERM u

WHERE group_id = g.user_id

AND group_member = u.user_id

Presents group information from SYSGROUP in a more readable format.


SYS.SYSINDEXES
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 49. SQL Anywhere System Views

Alphabetical list of views

SYS.SYSINDEXES

CREATE VIEW SYS.SYSINDEXES ( icreator, iname, fname, creator,

tname, indextype, colnames, interval, level )

AS

SELECT ( SELECT user_name FROM SYS.SYSUSERPERM

WHERE user_id = SYSINDEX.creator ),

index_name,

( SELECT file_name FROM SYS.SYSFILE

WHERE file_id = SYSINDEX.file_id ),

( SELECT user_name FROM SYS.SYSUSERPERM

WHERE user_id = SYSINDEX.creator ),

table_name,

IF "unique" = 'Y' THEN 'Unique'

ELSE 'Non-unique' ENDIF,

( SELECT list( string( column_name,

IF "order" = 'A' THEN ' ASC' i

ELSE ' DESC' ENDIF ) )

FROM SYS.SYSIXCOL == SYS.SYSCOLUMN

WHERE index_id = SYSINDEX.index_id ), 0, 0

FROM SYS.SYSTABLE KEY JOIN SYS.SYSINDEX

Presents index information from SYSINDEX and SYSIXCOL in a more readable format.


SYS.SYSOPTIONS
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 49. SQL Anywhere System Views

Alphabetical list of views

SYS.SYSOPTIONS

CREATE VIEW SYS.SYSOPTIONS ( user_name, "option", "setting" )

AS

SELECT ( SELECT user_name FROM SYS.SYSUSERPERM

         WHERE user_id = SYSOPTION.user_id ),

         "option", "setting"

FROM SYS.SYSOPTION

Displays option settings contained in the table SYSOPTION in a more readable format.


SYS.SYSPROCPARMS
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 49. SQL Anywhere System Views

Alphabetical list of views

SYS.SYSPROCPARMS

CREATE VIEW SYS.SYSPROCPARMS ( creator, parmname, procname,

parmtype, parmmode, parmdomain, length, remarks )

AS

SELECT ( SELECT user_name FROM SYS.SYSUSERPERM

         WHERE user_id = SYSPROCEDURE.creator ),

      parm_name, proc_name, parm_type,

      IF parm_mode_in = 'Y' AND

         parm_mode_out = 'N' THEN 'IN'

      ELSE IF parm_mode_in = 'N'

         AND parm_mode_out = 'Y' THEN 'OUT'

      ELSE 'INOUT' ENDIF ENDIF,

      ( SELECT domain_name FROM SYS.SYSDOMAIN

         WHERE domain_id = SYSPROCPARM.domain_id ),

      width, SYSPROCPARM.remarks

FROM SYS.SYSPROCPARM == SYS.SYSPROCEDURE

Lists all the procedure parameters from SYSPROCPARM in a readable format.


SYS.SYSREMOTEUSERS
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 49. SQL Anywhere System Views

Alphabetical list of views

SYS.SYSREMOTEUSERS

CREATE VIEW SYS.SYSREMOTEUSERS

AS SELECT(SELECT user_name FROM SYS.SYSUSERPERM AS u

      WHERE u.user_id=r.user_id) AS user_name,

    "consolidate",

    (SELECT type_name FROM SYS.SYSREMOTETYPE AS t

      WHERE t.type_id=r.type_id) AS type_name,

    "address",frequency,send_time,

    (IF frequency='A' THEN

      NULL

    ELSE

      IF frequency='P' THEN

        IF time_sent IS NULL THEN

          current timestamp

        ELSE

          (SELECT min(minutes(time_sent,

            60*hour(a.send_time)

            +minute(seconds(a.send_time,59))))

            FROM SYS.SYSREMOTEUSER AS a

            WHERE a.frequency='P'

            AND a.send_time=r.send_time)

        ENDIF

      ELSE

        IF current date+send_time

        >COALESCE(time_sent,current timestamp) THEN

          current date+send_time

        ELSE

          current date+send_time+1

        ENDIF

      ENDIF

    ENDIF) AS next_send,

   log_send,time_sent,log_sent,

   confirm_sent,send_count,resend_count,

   time_received,log_received,confirm_received,

   receive_count,rereceive_count

FROM SYS.SYSREMOTEUSER AS r

Lists the information in SYSREMOTEUSER in a more readable format.


SYS.SYSTABAUTH
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 49. SQL Anywhere System Views

Alphabetical list of views

SYS.SYSTABAUTH

CREATE VIEW SYS.SYSTABAUTH ( grantor, grantee,

   screator, stname, tcreator, ttname,

   selectauth, insertauth, deleteauth,

   updateauth, updatecols, alterauth, referenceauth )

AS

SELECT ( SELECT user_name FROM SYS.SYSUSERPERM

         WHERE user_id = SYSTABLEPERM.grantor ),

      ( SELECT user_name FROM SYS.SYSUSERPERM

         WHERE user_id = SYSTABLEPERM.grantee ),

      ( SELECT user_name

         FROM SYS.SYSUSERPERM == SYS.SYSTABLE

         WHERE table_id = SYSTABLEPERM.stable_id ),

      ( SELECT table_name FROM SYS.SYSTABLE

         WHERE table_id = SYSTABLEPERM.stable_id ),

      ( SELECT user_name FROM

         SYS.SYSUSERPERM == SYS.SYSTABLE

         WHERE table_id = SYSTABLEPERM.ttable_id ),

      ( SELECT table_name FROM SYS.SYSTABLE

         WHERE table_id = SYSTABLEPERM.ttable_id ),

      selectauth, insertauth, deleteauth,

      updateauth, updatecols,

      alterauth, referenceauthauth

FROM SYS.SYSTABLEPERM

Presents table permission information in SYSTABLEPERM in a more readable format.


SYS.SYSTRIGGERS
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 49. SQL Anywhere System Views

Alphabetical list of views

SYS.SYSTRIGGERS

CREATE VIEW SYS.SYSTRIGGERS ( owner, trigname, tname,

event, trigtime, trigdefn )

AS

SELECT ( SELECT user_name FROM SYS.SYSUSERPERM

         WHERE user_id = SYSTABLE.creator ),

      trigger_name, table_name,

      IF event = 'I' THEN 'INSERT'

      ELSE IF event = 'U' THEN 'UPDATE'

      ELSE IF event = 'C' THEN 'UPDATE'

      ELSE 'DELETE' ENDIF ENDIF ENDIF,

      IF trigger_time = 'B' THEN 'BEFORE'

         ELSE 'AFTER' ENDIF,

      trigger_defn

FROM SYS.SYSTRIGGER == SYS.SYSTABLE

WHERE foreign_table_id IS NULL

Lists all the triggers from SYSTRIGGER in a readable format.


SYS.SYSUSERAUTH
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 49. SQL Anywhere System Views

Alphabetical list of views

SYS.SYSUSERAUTH

CREATE VIEW SYS.SYSUSERAUTH ( name, password,    resourceauth, dbaauth, scheduleauth, user_group )

AS

SELECT user_name, password, resourceauth,

      dbaauth, scheduleauth, user_group

FROM SYS.SYSUSERPERM

Displays all the information in the table SYSUSERPERM except for user numbers. Since this view shows passwords, this system view does not have PUBLIC select permission. (All other system views have PUBLIC select permission.)


SYS.SYSUSERLIST
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 49. SQL Anywhere System Views

Alphabetical list of views

SYS.SYSUSERLIST

CREATE VIEW SYS.SYSUSERLIST ( name, resourceauth,

   dbaauth, scheduleauth, user_group )

AS

SELECT user_name, resourceauth,

      dbaauth, scheduleauth, user_group

FROM SYS.SYSUSERPERM

Presents all information in SYSUSERAUTH except for passwords.


SYS.SYSUSEROPTIONS
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 49. SQL Anywhere System Views

Alphabetical list of views

SYS.SYSUSEROPTIONS

CREATE VIEW SYS.SYSUSEROPTIONS ( "user_name",

   "option", "setting" )

AS

SELECT u.name, "option",

      isnull( ( SELECT "setting"

               FROM sys.sysoptions s

      WHERE s.user_name = u.name

      AND s."option" = o."option" ),

      "setting" )

FROM SYS.SYSOPTIONS o, SYS.SYSUSERAUTH u

WHERE o.user_name = 'PUBLIC'

Display effective permanent option settings for each user. If a user has no setting for an option, this view will display the public setting for the option.


SYS.SYSUSERPERMS
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 49. SQL Anywhere System Views

Alphabetical list of views

SYS.SYSUSERPERMS

CREATE VIEW SYS.SYSUSERPERMS

AS

SELECT user_id, user_name, resourceauth, dbaauth,

      scheduleauth, user_group, remarks

FROM SYS.SYSUSERPERM

Contains exactly the same information as the table SYS.SYSUSERPERM except the password is omitted. All users have read access to this view, but only the DBA has access to the underlying table (SYS.SYSUSERPERM).


SYS.SYSVIEWS
User's Guide

PART 6. SQL Anywhere Reference

CHAPTER 49. SQL Anywhere System Views

Alphabetical list of views

SYS.SYSVIEWS

CREATE VIEW SYS.SYSVIEWS ( vcreator, viewname, viewtext )

AS

SELECT user_name, table_name, view_def

FROM SYS.SYSTABLE KEY JOIN SYS.SYSUSERPERM

WHERE table_type = 'VIEW'

Lists views along with their definitions.


Glossary
User's Guide

PART 6. SQL Anywhere Reference

Glossary

About the glossary

address

article

atomic

authority

autocommit

backup

base data type

base table

batch

bind variable

buffer

business rules

cache

case sensitivity

check constraint

checkpoint

checkpoint log

client

client application

client/server

code page

collation

collation sequence

column

command file

command window

comment

commit

compound statement

compressed database file

concurrency

conflict trigger

connection

connection ID

connection parameters

connection string

consolidated database

constraint

container

correlated subquery

correlation name

cursor

cursors

cursor stability

daemon

data dictionary

data source

data type

database

database administrator

database application

database connection

database engine

database file

database name

database object

database owner

datagram

DBA

DBA authority

dbspace

DDE

DDE transactions

deadlock

default value

device

dirty

DLL

domain

driver

Dynamic Data Exchange

Embedded SQL

encryption

entity integrity

engine name

environment variable

entity

Entity-Relationship design

erase

ethernet

exception handler

exclusive lock

extraction

FILE

foreign key

foreign key constraint

foreign table

forward log

full backup

function

grant option

grantee

grantor

group

handle

host variable

identifier

incremental backup

index

inner join

integrity

interprocess communication

IPX

isolation levels

ISQL

join

join condition

join type

key join

key

LAN

local area network

locking

log files

MAPI

media failure

Message Agent

message system

message type

messages

named connection

named pipes

NDIS

NetBIOS

NetBEUI

NetWare

network adapter

network architecture

network card

network driver

network operating system

network server

NULL

nullability

ODBC

ODBC Administrator

ODI

Open Database Connectivity

optimizer

outer join

outer reference

owner

packet

page

page size

passthrough

password

performance statistics

permissions

phantom lock

precision

primary copy

primary table

projection

protocol

protocol stack

primary key

primary key constraint

programming interface

publication

publication update

publisher

remote database

remote permission

qualifier

query

read lock

referential integrity

relationship

remote DBA authority

remote user

replication

replication frequency

replication message

resource authority

role name

rollback

rollback log

root file

row

row-level trigger

runtime database engine

savepoint

scale

schema

search condition

serializable

server

service

session

size

SQL

SQLCA

sqlcode

sqlstate

SQLDA

SQL Remote

standalone engine

statement

statement-level trigger

store-and-forward

stored procedure

string

Structured Query Language

subquery

submission

subscriber

subscribing

subscription

subtransaction

synchronization

system failure

system catalog

system object

system tables

system views

table

TCP/IP

temporary table

token ring

topics

Transact-SQL

transaction

transaction blocking

transaction log

transaction log mirror

transaction processing

translation driver

trigger

two-phase commit

unique constraint

unique index

unload

updates

upgrade

user-defined data type

user account

user ID

validate

view

VIM

Watcom-SQL

Winsock

write file

write lock

WSQL DDE

WSQL HLI


Glossary


About the glossary

This glossary contains words used in the SQL Anywhere User's Guide and industry-wide terms concerning SQL databases and related technologies.


address

In SQL Remote replication, the destination of replication messages sent by a given message system. Publishers and remote users each have their own address. For a FILE message type, the address is a subdirectory name relative to the directory defined by the SQLREMOTE environment variable. This is typically on a volume that is shared between the replicating databases. SQL Remote stores its messages as replication files in this subdirectory. For a MAPI message type, the address is any valid MAPI address.


article

In SQL Remote replication, a database object that represents a whole table, or a subset of the rows and columns in a table. Articles are grouped together in publications.


atomic

A set of operations is atomic if it cannot be broken down into smaller pieces. Transactions are referred to as atomic because they must either be processed entirely or not at all.

The body of a procedure or trigger can be forced to be atomic by adding the keyword ATOMIC after the BEGIN keyword.


authority

Determines what structural actions a user can perform in a database. While most users will have no special authorities, a user with DBA authority can grant other users resource authority, DBA authority, or remote DBA authority.


autocommit

An ISQL option. If autocommit is set to TRUE, then a database COMMIT is performed after each successful command and a ROLLBACK after each failed command. The ODBC interface has a setting similar to autocommit. Users of applications communicating with SQL Anywhere through ODBC should check their application documentation for how to set this option. Developers programming directly to the ODBC interface should consult the ODBC documentation for information about implementing autocommit.


backup

It is important to make regular backups of your database files in case of media failure. A backup is a copy of the database file. You can make backups using the SQL Anywhere backup utility or using other archiving software of your choice.


base data type

One of the intrinsic (simple) data types included in SQL Anywhere (such as INTEGER). User-defined data types (including those supplied with SQL Anywhere) are built on base data types.


base table

The tables that permanently hold the data in the database are sometimes called base tables to distinguish them from temporary tables and from views.


batch

A batch is a set of SQL statements sent together to the database engine by an application.


bind variable

In Embedded SQL, a bind variable is a host variable. used to pass values to the database engine.


buffer

An area of memory reserved for some dedicated use, such as storing incoming messages for processing.


business rules

The rules to which the data in a database must conform are often called business rules, as they reflect organizations' operating practices.

For example, a business rule limiting customers' credit can be enforced by a trigger in a sales order table. A rule requiring library books to be returned within two weeks can be checked by constraints, so that reminders can be issued or fines calculated.


cache

To avoid having to access a hard disk every time it needs to retrieve or write information to the database, SQL Anywhere keeps data it may need to access again in the computer's memory, where access is much quicker. The area of memory set aside for this information is called a cache.


case sensitivity

When creating a database, you can choose whether identifiers in this database (table names, column names, and so on) and values are considered to be case-sensitive in comparisons and string operations.

If, for example, a database is case-sensitive, emp_id would not be the same as emp_ID.


check constraint

A check constraint allows specified conditions on a column or set of columns in a table to be verified.


checkpoint

A time at which all dirty pages held in cache are written to disk is called a checkpoint. Once all the dirty pages are written to disk, the checkpoint log is deleted. A checkpoint may occur for one of several reasons, at times specified by the user or decided internally by the database engine.


checkpoint log

A SQL Anywhere database file is composed of pages. Before a page is updated (made dirty), a copy of the original is always made. The copied pages are the checkpoint log. The checkpoint log is deleted when a checkpoint occurs.


client

Client is a widely-used term with several meanings. It refers to the user's side of a client/server arrangement: for example, an application that addresses a database, typically held elsewhere on a network, is called a client application.


client application

In a database context, a client application is any application that communicates with a database engine.


client/server

A software architecture where one application (the client) obtains information from and sends information to another application (the server).

In a database context, the server is a database engine, and the client is a database client application. The two applications often reside on different computers on a local area network.


code page

A code page is a character set. SQL Anywhere supports many different national languages and character sets, as long as they are available under the user's operating system.


collation

SQL Anywhere supports many different national languages by providing a choice of collations. Each collation specifies a code page (character set) and a sorting and comparison order for that code page. SQL Anywhere also supports custom collations.


collation sequence

A collation sequence is an ordering of characters used for sorting and comparing strings. Each national language employs a character set or code page, and a collation sequence for that set.


column

All data in relational databases such as SQL Anywhere is held in tables, composed of rows and columns. Each column holds a particular type of information.


command file

A text file containing SQL statements. Command files can be built by yourself (manually) or by database utilities (automatically). The DBUNLOAD utility, for example, creates a command file consisting of the SQL statements necessary to recreate a given database.


command window

The ISQL. command window is an edit control for entering SQL statements for execution.


comment

A text description of an object in the database. These remarks are not parsed or executed by the database engine.


commit

When a user sends the SQL command COMMIT, all the work done to that point is applied to the database itself, and can no longer be undone. A commit marks the end of a transaction.


compound statement

A compound statement is a set of SQL statements treated as a unit. The body of a procedure or trigger consists of a compound statement. A compound statement starts with BEGIN and finishes with END.


compressed database file

A database file that has been compressed to a smaller physical size using SQL Anywhere's database compression utility (DBSHRINK). To make changes to a compressed database file, you must use an associated write file. Compressed database files can be re-expanded into normal database files using SQL Anywhere's database uncompression utility (DBEXPAND).


concurrency

Multiuser versions of SQL Anywhere support concurrent applications: separate connections which may address the same data in the database, running at the same time. SQL Anywhere provides transaction processing and automatic row-level locking to ensure that information remains consistent and that each concurrent application sees a consistent set of data.


conflict trigger

In SQL Remote replication, a trigger that is fired when an update conflict is detected, before the update is applied. Specifically, conflict 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. They are fired before each row is updated.


connection

When a client application connects to a database, it specifies several parameters that govern all aspects of the connection once it is established. A user ID, a password, the name of the database to attach to, are all parameters that specify the connection. All exchange of information between the client application and the database to which it is connected is governed by the connection.


connection ID

A unique number that identifies a given connection between the user and the database.

You can determine your own connection ID using the following SQL statement inside that connection:

select connection_property( 'Number' )


connection parameters

When a client application connects to a database, the connection parameters specify the characteristics of the connection. See connection.


connection string

When a client application connects to a database, it uses connection parameters to specify the characteristics of the connection. These connection parameters are collected together as a connection string.

See also: connection parameters.


consolidated database

In SQL Remote replication, a database 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.


constraint

When tables and columns are created they may have constraints assigned to them. A constraint ensures that all entries in the database object. to which it applies satisfy a particular condition. For example, a column may have a UNIQUE 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 that in some other table.

See also: integrity, foreign key constraint, primary key constraint, column, table, unique constraint, check constraint.


container

In a graphical user interface, a container is an object that contains other objects. Containers can be expanded by double-clicking them.


correlated subquery

A subquery. that contains an outer reference.


correlation name

In a SQL SELECT query, a correlation name can be given to a table. The correlation name must then be used to refer to the table in the rest of the query.

A correlation name is a convenient way of reducing error and effort in developing long queries that refer to tables with complex names.


cursor

A cursor is a handle, or identifier, for a particular SQL query and for the position within the result set that is being accessed. Cursors allow each row of a query that returns more than one row to be processed by a client application individually.


cursors

A cursor is a handle, or identifier, for a particular SQL query and for the position within the result set that is being accessed. Cursors allow each row of a query that returns more than one row to be processed by a client application individually.


cursor stability

Cursor stability is a concurrency condition, guaranteed by choosing an isolation level of 1, 2, or 3. Cursor stability guarantees that no row fetched through a cursor yields uncommitted data.


daemon

A background process on a computer, running periodically or all the time, which manages a particular function such as printing services or network communication services.


data dictionary

See system tables.


data source

Databases available to ODBC applications are defined through data sources.

For a detailed description of ODBC data sources, see "Working with ODBC data sources".


data type

Each column in a table is associated with a particular data type. Integers, character strings, and dates are examples of data types.


database

A relational database is a collection of tables, related by primary and foreign keys. The tables hold the information in the 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.


database administrator

The database administrator (DBA) is a person responsible for maintaining 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 built in to SQL Anywhere databases as a user ID. When a database is initialized, a DBA user ID is created. The DBA user ID has authority to carry out any activity within the database.


database application

See client application.


database connection

All exchange of information between client applications and the database takes place in a particular connection. A valid user ID and password are required to establish a connection, and the actions that can be carried out during the connection are defined by the privileges granted to the user ID.


database engine

All access to information in a SQL Anywhere database goes through a SQL Anywhere engine. The specific SQL Anywhere engine you are using will depend on your operating system. Requests for information from a database are sent to the database engine, which carries out the instructions.


database file

A database is held in one or more distinct database files. The user does not have to be concerned with the organization of a database into files: requests are issued to the database engine about a database, and the engine knows in which file to look for each piece of required information.

Database administrators can create new database files for a database using the "CREATE DBSPACE statement" command.

Each table, together with its associated indexes, must be contained in a single database file.


database name

When a database is loaded by an engine, it is assigned a database name. Client applications can connect to a database by specifying its database name.

The default database name is the root of the database file.


database object

A database is made up of tables, indexes, views, procedures, and triggers. Each of these is a database object.


database owner

The user ID that creates a database is the owner of that database, and has the authority to carry out any changes to that database. The database owner is also referred to as the database administrator, or DBA. A database owner can grant permission to other users to have access to the database and to carry out different operations on the database, such as creating tables or stored procedures.


datagram

Communications across a network may take place in a session, (also called a connection, or virtual circuit) or in a connectionless manner. In the connectionless case, the independent packets of information are called datagrams, in analogy with telegrams.

Connectionless communications require routing decisions for all packets, and are not guaranteed. Multiuser editions of SQL Anywhere server use datagrams for their TCP/IP, IPX, and NetDG communication links.


DBA

An abbreviation for database administrator, also called the database owner. When a database is first created, using the DBINIT utility, it is created with the single user ID DBA, with password SQL.


DBA authority

DBA (DataBase Administrator) authority enables a user to carry out any activity in the database (create tables, change table structures, assign ownership of new objects, create new users, revoke permissions from users, and so on).

The DBA user has DBA authority by default.


dbspace

A SQL Anywhere database can be held in multiple files, called dbspaces. The SQL command CREATE DBSPACE adds a new file to the database.

Each table, together with its associated indexes, must be contained in a single database file.


DDE

Dynamic data exchange (DDE) is a method for Windows applications to communicate with each other. In any DDE conversation, one application is the client, or destination, while the other application is the server, or source.


DDE transactions

In DDE, a transaction is an exchange of information between the DDE client and the DDE server. poking, executing,, and requesting. are the three types of DDE transaction.


deadlock

A deadlock occurs when two or more concurrent. transactions become blocked in such a way that they cannot become unblocked. In this situation one of the transactions must roll back its work in order for the other transaction(s) to continue.


default value

Also known as a "column default" or just "default", this is a value that is automatically assigned to particular columns when a new row is entered into a database table, without any action on the part of the client application, as long as no value is specified by the client application. If the client application does specify a value for the column, it overrides the column's default value. Default values can be user-defined (a string or number) or pre-defined (e.g. a timestamp supplied by the system).


device

A device is a disk drive, a tape drive, or other information storage medium.


dirty

A database page is considered dirty when a change is made to it. Before a page is made dirty, a copy of the original page is made and held as the checkpoint log.


DLL

A dynamic link library, or DLL, is a collection of compiled functions that can be addressed by a running application at run time. DLL's allow a single set of functions to be shared by many applications, and can be updated without updating every application that depends on them. The Windows, Windows NT, and OS/2 operating systems support DLLs.


domain

Every column is associated with a particular domain: the data type and range of values that constitute valid data for that column.


driver

A piece of software that manages low-level functions on a computer, such as a communication with a network card. or a printer.


Dynamic Data Exchange

See DDE.


Embedded SQL

The native programming interface to SQL Anywhere from C programs. SQL Anywhere embedded SQL is an implementation of the ANSI and IBM standard.


encryption

Encryption makes it more difficult for someone to decipher the data in your database by using a disk utility to look at the file.  File-compression utilities are not able to compress encrypted database files as much as unencrypted ones.


entity integrity

Each row in every table in a database must be uniquely identifiable in order to be accessed by the database engine. Each row is identified by its primary key. This requirement of identifiability is called entity integrity, and is automatically ensured by SQL Anywhere through a checking of the primary key.


engine name

When a database engine is started it is assigned an engine name. Client applications specify the engine to which they want to connect by using the engine name.

The default engine name is the first database name.


environment variable

The DOS and OS/2 operating systems allow users to set environment variables that can be used by applications to identify system-specific information. Windows applications have access to DOS environment variables. SQL Anywhere uses the SQLCONNECT and SQLANY environment variables to identify default connection parameters and home directory for SQL Anywhere.


entity

In Entity-Relationship design. of databases, a first step is to identify the entities in the information you will incorporate into your database. Entities become tables in the final implementation.


Entity-Relationship design

Entity-Relationship design is a systematic approach to designing databases, based on a top-down analysis of the tasks you need to perform.

See also: the chapter "Designing Your Database".


erase

Erasing a database deletes all tables and data from disk, including the transaction log that records alterations to the database.


ethernet

Ethernet is a term associated with network cards, a protocol, and a network topology. In a network topology context, an ethernet is commonly associated with a bus network.


exception handler

In procedures and triggers, an exception handler is defined in the EXCEPTION part of a compound statement, and is code that is executed if an error is encountered in the compound statement.


exclusive lock

A lock is exclusive when other transactions cannot acquire a lock of similar type on a row. The write lock. is exclusive, while the read lock. is nonexclusive.


extraction

In SQL Remote replication, the act of synchronizing a remote database with its consolidated database by unloading the appropriate structure and data from the consolidated database, then reloading it into the remote database. Extraction uses direct manipulation of ordinary files—it does not use the SQL Remote message system.


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).


foreign key

Tables are related to each other by using foreign keys. A foreign key in one table (the foreign table) contains a value corresponding to the primary key of another table (the primary table). This relates the information in the foreign table to that in the primary table.

See also: primary key, referential integrity.


foreign key constraint

A foreign restricts the values for a set of columns to match the values in a primary key or uniqueness constraint of another 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. Imposing a foreign key constraint on a set of columns makes that set the foreign key. in a foreign key relationship.

See also: constraint.


foreign table

A foreign table is the table containing the foreign key in a foreign key relationship.

See also: foreign key, primary table. referential integrity.


forward log

See transaction log.


full backup

In a full backup, a copy is made of the entire database file itself, and optionally of the transaction log. A full backup contains all the information in the database.


function

Also called a "user-defined function", this is a type of procedure that returns a single value to the calling environment. A function can be used, subject to permissions, in any place that a built-in non-aggregate function is used.


grant option

When a user is granted a permissino WITH GRANT OPTION, they grant the permission can in turn to other users.


grantee

A user ID receiving a permission from another user ID is a grantee.


grantor

The user ID granting a permission to another user ID is the grantor.


group

A user group is a database user ID that has been given the permission to have members. User groups are used to make the assignment of database permissions simpler. Rather than assign permissions to each user ID, a user ID is assigned to a particular group, and takes on the permissions assigned to that group.


handle

A handle is an integer that uniquely identifies an object. ODBC. makes use of handles to identify environments, connections, and statements.


host variable

In Embedded SQL, a host variable is a C variable which is identified to the SQL preprocessor. Host variables can be used to send values to the database engine or receive values from the database engine.

See also: bind variable.


identifier

An identifier is any string composed of the characters A through Z, a through z, 0 through 9, underscore (_), at sign (@), number sign (#), or dollar sign ($). The first character must be a letter. Alternatively, any string of characters can be used as an identifier by enclosing it in double quotes.


incremental backup

An incremental backup is a copy of the transaction log. This log contains all the information needed to restore the database to its present state from its state when the transaction log was started.


index

An index on one or more columns of a database table allows fast lookup of the information in these columns, and so can greatly speed up database queries. Specifically, indexes assist WHERE clauses in SELECT statements.


inner join

An inner join is one kind of JOIN. operation allowed in the FROM clause of SELECT queries. INNER JOIN is the default type of join.

An inner join includes only those rows of the table on each side of the expression that has matching rows in the other table.

For a full description, see "FROM clause".

See also: outer join.


integrity

Integrity of information in a database ensures that each row in the database can be uniquely identified (entity integrity) and that relations between rows in different tables are properly maintained (referential integrity). SQL Anywhere provides several tools for maintaining the integrity of information in databases.


interprocess communication

In operating systems that enable several applications to run at once, interprocess communication allows applications to work together.

For example, Named pipes. is a method of interprocess communication supported by OS/2 and Windows NT. DDE. is a method of interprocess communication supported by the Microsoft Windows operating environment and the Windows NT operating system.


IPX

IPX is a network-level protocol. by Novell.


isolation levels

The isolation level for instructions within a transaction determines the extent to which other transactions may share the data addressed by the transaction. The isolation level can be set by the user: different isolation levels are appropriate for different kinds of transaction.


ISQL

ISQL (Interactive SQL) is a SQL Anywhere database administration and browsing utility.


join

The JOIN clause in a SELECT query enables a single database query to obtain information from several related tables.


join condition

For any join type. in a join. clause of a SQL query, except for a cross join, a join condition can be specified.

See also: "FROM clause".


join type

A JOIN. clause in a SELECT query is one of several join types. The join types supported by SQL Anywhere are cross join, natural join, key join, inner join, and outer join.


key join

A key join is a join type. used in SELECT queries that take information from more than one table. The key join restricts results to rows where the foreign key value in one table is equal to the corresponding primary key value in the other table.


key

Database tables may contain two types of key: a primary key, and a foreign key.


LAN

See local area network.


local area network

A local area network (LAN) is a collection of networked computers characterized by two attributes:

♦	A diameter of not more than a few kilometres.

♦	Ownership by a single organization.

See also: protocol.


locking

SQL Anywhere places a lock on a row that is being addressed by a transaction. The lock prevents other transactions from having access to the row in a way that could make the data in the database or the data seen by users of client applications inconsistent, while allowing concurrent transactions.


log files

SQL Anywhere maintains a set of three log files to ensure that the data in the database is recoverable in the event of a system or media failure, and to assist database performance.


MAPI

Microsoft's Message Application Programming Interface, a message system used in several popular e-mail systems such as Microsoft Mail.


media failure

A media failure occurs when the information on a medium (typically a hard disk drive) becomes unusable. A media failure may occur as a result of damage to the file, the file system, or the actual device. SQL Anywhere includes tools for backup and recovery to minimize the effects of media failure.


Message Agent

In SQL Remote replication, a program (DBREMOTE) that sends and receives replication messages on behalf of a database. A consolidated database's message agent typically runs continuously, receiving replication messages continuously and sending replication messages periodically, while a remote database's agent typically runs on demand, receiving and sending all pending messages.


message system

In SQL Remote replication, a protocol for exchanging messages between the consolidated database and a remote database. SQL Anywhere includes support for a FILE message system (using shared files) and the MAPI message system. In most cases, a consolidated database and a remote database(s) will send and receive messages using the same message system.


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. A message type is named after a message system (e.g. MAPI), and includes the publisher address for that message system (e.g. a valid MAPI address).


messages

Message based communication between applications or computers does not require a direct connection. Instead, a message sent at one time by an application can be received at another time by another application at a later time.


named connection

Any connection from ISQL or and embedded SQL application to a database may optionally be given a name. If a client application has several connections in place simultaneously, the user may switch from one connection to another by using the SET CONNECTION command.


named pipes

Named Pipes are an interprocess communication mechanism implemented by a number of leading operating system vendors. Named Pipes are usually implemented atop some transport-level protocol.


NDIS

NDIS (Network Driver Interface Specification) is a datalink-level protocol jointly defined by Microsoft and IBM.


NetBIOS

NetBIOS is a transport-level interface defined by IBM.


NetBEUI

NetBEUI is a transport-level protocol.


NetWare

A widely-used network operating system. by Novell. NetWare generally employs the IPX protocol, although the TCP/IP protocol may also be used.


network adapter

A network adapter is the physical attachment to a computer allowing network communication. Also called a network card.

See also: network driver.


network architecture

A network architecture is the physical interconnection of computers on a network. Typical architectures include bus, where all computers connect to a single carrier, and ring, where one computer is directly connected to another to form a closed ring.


network card

A network card is the physical attachment to a computer allowing network communication. Also called a network adapter.

See also: network driver.


network driver

A network driver is the software logically located between the operating system and the network card, which allows applications to communicate to the network card. Network cards are usually bundled with a number of network drivers for various operating systems and network protocols.


network operating system

An operating system optimized for server deployment, such as Novell NetWare and Microsoft Windows NT Server Edition.


network server

A SQL Anywhere database engine that runs on a different PC from the client application (which uses the SQL Anywhere client). The server communicates with the client using a particular network protocol.

A network server can support many users connecting from many PCs on the network.


NULL

The NULL value is a special value for a database entry, different from any other valid value for any data type. The NULL value represents missing or inapplicable information.


nullability

Determines whether a column allows a NULL value to be assigned to it. Columns are typically allowed to be NULL if their values are optional or not always available, and are not required for the data in the database be correct.


ODBC

The Open Database Connectivity (ODBC) interface, defined by Microsoft Corporation, is a standard interface to database management systems in the Windows and Windows NT environments. ODBC is one of several interfaces supported by SQL Anywhere.


ODBC Administrator

The ODBC. Administrator is a Microsoft program included with SQL Anywhere for setting up ODBC data sources.


ODI

ODI (Open Datalink Interface) is a data link-level interface defined by Novell.


Open Database Connectivity

See ODBC.


optimizer

The SQL Anywhere database engine contains an optimizer which attempts to pick the best strategy for executing each query. The optimizer uses educated guesses about the occurrence of particular elements in the database to select a strategy. The user can provide explicit estimates in order to help tune an execution strategy.


outer join

An outer join is one kind of JOIN. operation allowed in the FROM clause of SELECT queries.

An outer join may be either a LEFT OUTER or a RIGHT OUTER join. An outer join includes all rows of the table on the LEFT (RIGHT) of the expression whether or not there are matching rows in the other table.

See also inner join.


outer reference

A WHERE clause in a subquery. can refer to columns in tables that do not form part of the subquery, but do form part of the main query. This kind of reference is called an outer reference. A subquery that contains an outer reference is called a correlated subquery.


owner

Each object of a database is owned by the user ID that created it. The owner of a database object has rights to do anything with that object.


packet

A packet is a communication entity between processes. Messages between two processes are usually fragmented into a number of packets for data transmission from the source and then reassembled at the target host into a single message.


page

A SQL Anywhere database file is composed of pages. Before a page is updated (made dirty), a copy of the original is always made in memory. The copied pages are the checkpoint log. The page-size of a database file is specified when the database is created.


page size

The size of each database page (in bytes). The page size can be 512, 1024, 2048 or 4096 bytes, with 1024 being the default.  Other values for the size will be changed to the next larger size. Large databases usually benefit from a larger page size.


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 remote users (you can specify all remote users, individual users, or those users who subscribe to given publications). 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.


password

Whenever a user connects to a database, a password must be specified. The passwords are stored in the SYS.SYSUSERPERM system table, to which only the DBA has access.


performance statistics

Values that reflect the performance of the database system with respect to disk and memory usage. The CURRREAD statistic, for example, represents the number of file reads issued by the engine which have not yet completed.


permissions

Each user has a set of permissions that govern the actions they may take while connected to a database. Permissions are assigned by the DBA or by the owner of a particular database object.


phantom lock

A phantom lock is one of three types of lock supported by SQL Anywhere to support concurrency, as part of SQL Anywhere's transaction processing. capabilities.

A phantom lock is a type of read lock employed at isolation level 3. No other transaction can read or update the row once a phantom lock has been acquired.

See also: read lock, write lock, locking.


precision

For decimal and numeric data types, the total number of digits (including scale) allowed in the number.


primary copy

In a replication installation, the primary copy of any data is considered to hold the original of the data. All other places in which the piece of data is held are copies of this original.


primary table

A primary table is the table containing the primary key in a foreign key relationship.

See also: primary key, foreign table, referential integrity.


projection

The result of a SELECT query with DISTINCT specified has all duplicate rows eliminated, compared to the result that would be obtained without the DISTINCT specifier.

The DISTINCT result is called the projection of the result.


protocol

The rules and conventions used to communicate between computers are collectively known as a protocol. Instances of protocols include IPX, NetBEUI, and IP. The SQL Anywhere client and server can communicate using a number of different protocols, including NetBIOS, IPX, NamedPipes and TCP/IP.

See also: IPX, NetBIOS, Named Pipes, TCP/IP.


protocol stack

Network communications between communications take place according to a set of protocols. These protocols are logically organized in layers, each with a different function. The set of layers forms a protocol stack.


primary key

Each table in a relational database must be assigned a primary key. The primary key is a column, or set of columns, whose values uniquely identify every row in the table.


primary key constraint

A primary key constraint identifies one or more columns that uniquely identify each row in a table. Imposing a primary key constraint on a set of columns makes that set the primary key. for the table. The primary key usually identifies the best identifier for a row.

See also: constraint.


programming interface

Programs may connect to SQL Anywhere using one of the interfaces supported by SQL Anywhere. Embedded SQL. is SQL Anywhere's native interface. ODBC. is another low-level interface. WSQL DDE. and WSQL HLI. provide higher level interfaces.


publication

In SQL Remote replication, a database object that describes data to be replicated. A publication consists of articles (tables or subsets of tables). Periodically, the changes made to each publication in a database are replicated to all subscribers to that publication as publication updates.


publication update

In SQL Remote replication, a periodic batch of changes made to one or more publications in one database. A publication update is sent as part of a replication message to the remote database(s).


publisher

In SQL Remote replication, the single user in a database that can exchange replication messages with other replicating databases.


remote database

In SQL Remote replication, a database that exchanges replication messages with a consolidated database. Remote databases may contain all or some of the data in the consolidated database.


remote permission

In SQL Remote replication, the permission to exchange replication messages with the publishing database. Granting remote permissions to a SQL Anywhere user make them a remote user. This requires you to 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).


qualifier

The name of a database object, such as a table or a view, may be preceded by a qualifier to indicate its owner and hence uniquely identify the database object. For example, a table named some_table created by a user A_User can be uniquely identified as A_User.some_table.

Columns in tables or views may likewise be qualified by the table name (and owner) to identify them uniquely. For example, a column this_column may have the fully qualified name User.some_table.this_column.

Use of fully qualified names in SQL queries helps to avoid ambiguities.


query

Information is retrieved from SQL Anywhere databases by submitting a query. A query is an SQL SELECT statement, the clauses of which specify the exact information the database engine must return tot he client application.


read lock

A read lock is one of three types of lock supported by SQL Anywhere to support concurrency, as part of SQL Anywhere's transaction processing. capabilities.

When a transaction. reads a row, employing one of the more secure isolation levels. available (level 2 or 3), other transactions can read the row, but cannot update it.

See also: phantom lock, write lock, locking.


referential integrity

The tables of a relational database are related to each other by foreign keys. SQL Anywhere provides tools that maintain the referential integrity of the database: that is, ensure that the relations between the rows in different tables remain valid.


relationship

A step in the Entity-Relationship design. of databases, is to identify the relationships between the entities that you have identified.

One-to-many and one-to-one relationships become foreign key. relationships in the final implementation, while a many-to-many relationship becomes a table.


remote DBA authority

The Message Agent should be run using a user ID with REMOTE DBA authority, to ensure that actions can be carried out, without creating security loopholes.


remote user

In SQL Remote replication, a SQL Anywhere user who has been granted remote permissions in a replication setup. When the remote database is extracted from the consolidated database, the remote user becomes the publisher of the remote database, able to exchange publication updates with the consolidated database. While SQL Anywhere groups can also be granted remote permissions, note that users in these "remote groups" do not inherit remote permissions from their group.


replication

For databases, a process by which the changes to data in one database (including creation, updating, and deletion of records) are also applied to the corresponding records in other databases. SQL Anywhere supports replication using SQL Remote or Sybase 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. The frequency can be specified as on-demand, every given interval, or at a certain time of day.


replication message

In SQL Remote replication, a discrete communication that is sent from a publishing database to a subscribing database. Messages can contain a mixture of publication updates and passthrough statements (manual SQL statements such as DDL).


resource authority

Resource authority is the permission to create and modify objects of a database schema. Resource authority can be granted only by the DBA.


role name

Each foreign key is assigned a name, called a role name, to distinguish it from other foreign keys in the same table. If no role name is specified by the user, the role name is set to the name of the primary table.


rollback

When a user sends a rollback SQL statement to the database engine, all work since the last savepoint or since the beginning of the current transaction is undone, and no changes are made to the database by any of the instructions.


rollback log

A log kept in order to cancel changes made to database tables. The rollback log is needed in the event of a ROLLBACK request or a system failure. There is a separate rollback log for each transaction. When a transaction is complete, its rollback log is deleted.


root file

Unless you specifically create multiple files for your database using the CREATE DBSPACE statement, the database root file is the file your database is held in: the database file.

If your database is held in multiple database files, the root file is the first file created, which holds the system tables. When supplying the database file parameter in a connection string, you need to supply the root file name.


row

All data in relational databases such as SQL Anywhere is held in tables, composed of rows and columns. Each row holds a separate occurrence of each column. In a table of employee information, for example, each row contains information about a particular employee.


row-level trigger

A trigger that executes BEFORE or AFTER each row modified by the triggering insert, update, or delete operation is changed.


runtime database engine

The SQL Anywhere Desktop Runtime engine is a royalty-free redistributable database engine. The runtime database engine supports all the database manipulation language features of the full SQL Anywhere, with the exception of procedures and triggers. Also, the runtime database engine does not employ a transaction log.


savepoint

Within a transaction, a SAVEPOINT statement allows flexibility in committing and rolling back work. Work since the most recent savepoint can be undone using ROLLBACK TO SAVEPOINT. The RELEASE SAVEPOINT disallows any future rollbacks to the most recent savepoint. Before SQL Anywhere version 4.0, savepoints were called subtransactions.


scale

For decimal and numeric data types, the number of digits allowed after the decimal point.


schema

The structure of a database is called the schema. The schema is held in the system tables.

The schema includes the complete definitions of each database object. in the database, including tables, indexes, views, procedures, and triggers.


search condition

In SQL, a search condition is a WHERE clause in a SELECT statement.


serializable

A set of concurrent operations is executed in a serializable manner if the net effect of the execution is identical to the result of executing each operation in turn, without any concurrency.

An isolation level of 3 is needed to guarantee the serializable execution of transactions.


server

In SQL Anywhere, servers are database engines—the programs that manage the physical structure of the database and process queries on its data. Servers can be standalone engines or network servers.

In Sybase Central, standalone engines and network servers are both called servers.


service

In the Windows NT operating system, applications set up as NT services can run even when the user ID starting them logs off the machine.

Running a SQL Anywhere database server as a service under NT allows databases to keep running while not tying up the machine on which they are running.


session

Communications across a network may take place in a session, (also called a connection, or virtual circuit) or in a connectionless manner, using a datagram. method. When a connection is established, a route from the source computer to the destination computer is part of the session setup, and routing decisions are not required for every packet.

Network server editions of SQL Anywhere use sessions for their NetBIOS and local Named Pipes communication links.


size

For certain data types, the number of characters that the data type can contain.


SQL

Structured Query Language (SQL) is the language used to communicate to SQL Anywhere databases. SQL is very widely used in database applications, and in order to ensure compatibility among databases, SQL is the subject of standards set by several standards bodies.


SQLCA

A SQL Connection Area (SQLCA) is a segment of database client application code that manages the connection parameters governing the connections between the client application and a database.


sqlcode

A numeric error code identifying database errors.


sqlstate

A numeric error code identifying database errors. SQL Anywhere provides both the ODBC SQLSTATE, returned to ODBC applications, and the ANSI SQLSTATE, which is returned in the SQLCA to Embedded SQL applications.


SQLDA

The SQL Descriptor Area (SQLDA) is a data structure used for passing dynamic SQL statements to the database engine in Embedded SQL.


SQL Remote

An asynchronous message-based replication system for two-way server-to-laptop, server-to-desktop, and server-to-server replication between SQL Anywhere databases.


standalone engine

A SQL Anywhere  database engine that runs on the same PC as the client application.  A standalone engine is typically for a single user on a single PC, but can support several concurrent connections from that user.


statement

SQL allows several kinds of statement. Some statements modify the data in a database (commands), others request information from the database (queries), and others modify the database schema itself.


statement-level trigger

A trigger that executes after the entire triggering statement is completed.


store-and-forward

Store-and-forward exchange of information is typical of message based systems, and allows information to be exchanged without a direct connection between applications.


stored procedure

Stored procedures are procedures kept in the database itself, which can be called from client applications. Stored procedures provide a way of providing uniform access to important functions automatically, as the procedure is held in the database, not in each client application.


string

In SQL, a string is any sequence of characters enclosed in apostrophes ('single quotes'). To represent an apostrophe inside a string, use a sequence of two apostrophes. To represent a new line character, use a backslash followed by an n (\n). To represent a backslash character, use a sequence of two backslashes (\\).


Structured Query Language

See SQL.


subquery

A subquery is a component of a SQL query (SELECT statement) that is itself a query. Subqueries are important tools in constructing complex queries to databases.


submission

In a SQL Remote installation, changes made to a remote database and sent to the consolidated database are a submission. If and only if the changes are successfully applied at the consolidated database they will be replicated to other databases.


subscriber

In SQL Remote replication, a remote user who is subscribed to one or more of a database's publications.


subscribing

In a Replication Server or SQL Remote installation, a database that has subscribed to a replication or publication receives updates of changes to the data in that replication or publication.


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. The user's subscription may include an argument (value) for the publication's SUBSCRIBE BY parameter (if any).


subtransaction

See savepoint.


synchronization

In SQL Remote replication, the process by which 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 database. Synchronization is performed during the initial extraction of the remote database from the consolidated database, and may also be necessary later if a remote database becomes corrupt or gets out of step with the consolidated database (and cannot be repaired using passthrough mode). Synchronization can be accomplished by bulk extraction (the recommended method), by manually loading from files, or by sending synchronization messages through the message system.


system failure

A system failure occurs when a power failure or some other failure causes a computer to fail while there are partially completed transactions. See also: media failure, transaction, backup.


system catalog

The system catalog is the list of all tables and views in the database.

The SQL Anywhere system view SYS.SYSCATALOG presents this information.


system object

In a database, a table, view, stored procedure, or user-defined data type that is pre-defined by SQL Anywhere. System tables store information about the database itself, while system views, procedures, and user-defined data types largely support Sybase Transact-SQL compatibility.


system tables

Every SQL Anywhere database includes a set of tables called the system tables, which hold information about the database structure itself: descriptions of the tables, users and their permissions, and so on.

The system tables are created and maintained automatically by the database engine. They are owned by the special user ID SYS, and cannot be modified by database users.


system views

Every SQL Anywhere database includes a set of views, which present the information held in the system tables. in a more easily understood format.


table

All data in relational databases is stored in tables. Each table consists of rows and columns. Each column carries a particular kind of information (a phone number, a name, and so on), while each row specifies a particular entry. Each row in a relational database table must be uniquely identifiable by a primary key.


TCP/IP

Transmission Control Protocol/Internet Protocol (TCP/IP) is a network protocol supported by SQL Anywhere


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.


token ring

A token ring is a specification of a particular network architecture. and protocol. A ring architecture is a topology is which every computer on the ring has a wire in and a wire out and forms a closed loop. A token is passed around the ring to arbitrate between computers that wish to communicate at the same time.


topics

Each separate panel in an online help system is a topic.


Transact-SQL

The SQL dialect used in Sybase SQL Server. SQL Anywhere supports a large subset of Transact-SQL.


transaction

A transaction is a logical unit of work that should be processed in its entirety by the database (though not necessarily at once) or not at all. SQL Anywhere supports transaction processing, with locking features built in to allow concurrent transactions to access the database without corrupting the data. Transactions begin following a COMMIT or ROLLBACK statement and end either with a COMMIT statement, which makes all the changes to the database required by the transaction permanent, or a ROLLBACK statement, which undoes all the changes made by the transaction.


transaction blocking

A transaction becomes blocked when it must wait for another transaction to finish before it can carry out its task. Proper design of transactions by application developers can minimize the occurrence of transaction blocks, which slow down database operation.


transaction log

A log storing 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. The transaction log should therefore be kept on a different device from the database files for optimal security.


transaction log mirror

An identical copy of the transaction log file, maintained at the same time.  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.


transaction processing

A database engine that supports transaction processing is capable of ensuring that the results of each transaction are either stored in the database in their entirety or not at all. Transaction processing is a key element in promoting secure and reliable databases.


translation driver

A translation driver. is a part of the data link layer of a protocol stack. Data link layers conform to either ODI. or NDIS. specifications, and translation drivers supplied by networking software vendors enable multiple protocol stacks, requiring both ODI and NDIS drivers, to operate with a single network adapter.


trigger

A trigger is a procedure stored in the database that is executed automatically by the database engine whenever a particular action occurs, such as a row being updated. Triggers are used to enforce complex forms of referential integrity, or to log activity on database tables.


two-phase commit

A mechanism to coordinate transactions across multiple database servers; only needed for distributed databases.


unique constraint

A unique constraint identifies one or more columns that uniquely identify each row in the table. A table may have several unique constraints.


unique index

A unique index on a table is an index for which it is ensured that no two rows have identical values in all columns in the index.


unload

Unloading a database dumps the structure and/or data of the database to text files (command files for the structure, ASCII comma-delimited files for the data). This may be useful for creating extractions, creating a backup of your database, or building new copies of your database with the same or slightly modified structure. You can also unload the data (but not the structure) of a particular table.


updates

In replication, each set of changes sent from one database to another is an update to a publication or replication.


upgrade

A major release of SQL Anywhere generally means a revised internal database format (to support new database features). When you upgrade your SQL Anywhere software to a major revision (for example, moving from 4.0 to 5.0), you should upgrade your existing databases to the new database format (after making backups of them).


user-defined data type

A named combination of base data type, default value, check condition, and nullability. Defining similar columns using the same user-defined data type encourages consistency throughout the database.


user account

Every connection with a database requires a user account. The permissions that a user has are tied to their user account. A user account consists of a user ID and password.


user ID

A string of characters that identifies the user when connecting to a particular database. The user ID, together with a password, constitute a user account.


validate

When the information in a database, or a database table, is checked for integrity it is validated. See also: entity integrity, referential integrity.


view

A view is a computed table. Every 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 can be useful for security purposes, and to tailor the appearance of database information to make data access straightforward. As a permanent part of the database schema, a view is a database object. See also: table, database object.


VIM

Vendor-Independent Messaging, a message system used in cc:Mail and Lotus Notes.


Watcom-SQL

The SQL dialect used in SQL Anywhere. Watcom-SQL conforms closely to ANSI SQL.


Winsock

Winsock is a specification of the socket library with extensions. The socket library is a collection of functions used to interface to a number of different transport-level protocols. The socket library was initially specified by the University of California at Berkeley for the TCP/IP protocol.


write file

If a database is used with a write file, all changes made to the database do not modify the database itself, but instead are made to the write file. Write files are useful in applications development, so the developer can have access to the database without interfering with it. Also, write files are used in conjunction with compressed databases and other read-only databases.


write lock

A write lock is one of three types of lock supported by SQL Anywhere to support concurrency, as part of the SQL Anywhere transaction processing. capabilities.

When a transaction. updates or inserts a row, it acquires a write lock on the row. No other transaction can acquire a lock on the same row.


WSQL DDE

A high level programming interface to SQL Anywhere for Windows applications.


WSQL HLI

A high level programming interface to SQL Anywhere.


"Transact-SQL COMMIT statement".


"Transact-SQL BEGIN TRANSACTION statement".


"Transact-SQL PRINT statement"

"Transact-SQL RAISERROR statement"


MESSAGE Statement


CREATE TRIGGER Statement


wsqlquerytomem.


OPEN, PREPARE, DECLARE.


ROLLBACK.


DROP, FETCH, OPEN, PREPARE.


PREPARE, DECLARE.


PREPARE, DECLARE, DROP.


DECLARE, PREPARE, OPEN.


DECLARE, PREPARE, FETCH, CLOSE, DROP.


DECLARE, DROP, OPEN, EXECUTE.


COMMIT.


START USING DATABASE, STOP USING DATABASE.


STOP USING DATABASE, SET CONNECTION.


START USING DATABASE, SET CONNECTION.


"The database engine"


The chapter "Using the Open Server Gateway", "The Open Server Stop utility", "The Open Server Information utility",.


"The Open Server Gateway", "The Open Server Stop utility".


"The Open Server Gateway", "The Open Server Information utility".


DBINIT, DBUNLOAD, ISQL


"The C language SQL preprocessor"


Search conditions

"SQL Anywhere Data Types"


Expressions


Numeric functions

String functions

Date and time functions

Data type conversion functions

System functions

Miscellaneous functions


Aggregate functions

String functions

Date and time functions

Data type conversion functions

System functions

Miscellaneous functions


Aggregate functions

Numeric functions

Date and time functions

Data type conversion functions

System functions

Miscellaneous functions


Aggregate functions

Numeric functions

String functions

Data type conversion functions

System functions

Miscellaneous functions


Aggregate functions

Numeric functions

String functions

Date and time functions

System functions

Miscellaneous functions


Aggregate functions

Numeric functions

String functions

Date and time functions

Data type conversion functions

Miscellaneous functions


Aggregate functions

Numeric functions

String functions

Date and time functions

Data type conversion functions

System functions


DEALLOCATE DESCRIPTOR statement

"The SQL descriptor area (SQLDA)"


CREATE DBSPACE statement


CREATE PROCEDURE statement


CREATE PUBLICATION statement

DROP PUBLICATION statement


CREATE REMOTE MESSAGE TYPE statement


CREATE TABLE statement

DROP statement

"SQL Anywhere Data Types"


CREATE TRIGGER statement

DROP statement


CREATE VIEW statement

DROP statement


CREATE PROCEDURE statement

GRANT statement

The chapter "Using Procedures, Triggers, and Batches"


Compound statements

The chapter "Using Procedures, Triggers, and Batches"


OPEN statement

DECLARE CURSOR statement

PREPARE statement


ROLLBACK statement

PREPARE TO COMMIT statement

CONNECT statement

SET CONNECTION statement

DISCONNECT statement


DECLARE CURSOR statement

DECLARE TEMPORARY TABLE statement

LEAVE statement

SIGNAL statement

RESIGNAL statement

The chapter "Using Procedures, Triggers, and Batches"


SET OPTION statement


GRANT statement

DISCONNECT statement

SET CONNECTION statement


DROP statement

"SQL Anywhere Data Types"


DROP statement


DROP statement

Compound statements

CREATE PROCEDURE statement

RETURN statement

The chapter "Using Procedures, Triggers, and Batches"


DROP statement


DROP statement

CALL statement

Compound statements

GRANT statement

CREATE FUNCTION statement

EXECUTE IMMEDIATE statement

The chapter "Using Procedures, Triggers, and Batches"


ALTER PUBLICATION statement

DROP PUBLICATION statement


GRANT PUBLISH statement

GRANT REMOTE statement

GRANT CONSOLIDATE statement

"SQL Remote message types"


CREATE TABLE statement

CREATE VIEW statement

GRANT statement


DROP SUBSCRIPTION statement

GRANT REMOTE statement

SYNCHRONIZE SUBSCRIPTION statement

START SUBSCRIPTION statement

"Setting up subscriptions",


DROP statement

ALTER TABLE statement

CREATE DBSPACE statement

"SQL Anywhere Data Types"

"Creating tables"


Compound statements

CREATE PROCEDURE statement

DROP statement

The chapter "Using Procedures, Triggers, and Batches"


Compound statements

"SQL Anywhere Data Types"

DROP VARIABLE statement

SET statement


DROP statement

CREATE TABLE statement


The chapter "SQL Anywhere Components"


"Host variables"


PREPARE statement

OPEN statement

EXPLAIN statement

SELECT statement

CALL statement


CREATE TABLE statement

"Using compound statements"


ALLOCATE DESCRIPTOR statement

"The SQL descriptor area (SQLDA)"


TRUNCATE TABLE statement

INSERT statement

INPUT statement

FROM clause


UPDATE statement

UPDATE (positioned) statement

INSERT statement

PUT statement


DECLARE CURSOR statement

PREPARE statement


CONNECT statement

SET CONNECTION statement


CREATE DATATYPE statement

CREATE DBSPACE statement

CREATE TABLE statement

CREATE INDEX statement

CREATE VIEW statement

CREATE PROCEDURE statement

CREATE FUNCTION statement

CREATE TRIGGER statement

ALTER TABLE statement


CONNECT statement


CREATE PUBLICATION statement


CREATE REMOTE MESSAGE TYPE statement

ALTER REMOTE MESSAGE TYPE statement

"SQL Remote message types",


PREPARE statement


CREATE VARIABLE statement

SET statement


CREATE SUBSCRIPTION statement


PREPARE statement

DECLARE CURSOR statement


CREATE PROCEDURE statement

Compound statements


SET OPTION statement


DECLARE CURSOR statement

PREPARE statement

FETCH statement

CLOSE statement

OPEN statement

"Cursors in Embedded SQL"

"The SQL communication area (SQLCA)"


DECLARE CURSOR statement

PREPARE statement

OPEN statement

"Cursors in Embedded SQL"

"Using cursors in procedures and triggers"


DECLARE CURSOR statement

FETCH statement

LEAVE statement

LOOP statement


SELECT statement

UPDATE statement

DELETE statement

"Search conditions"


FETCH statement

"Transact-SQL READTEXT statement"

"Transact-SQL WRITETEXT statement"


ALLOCATE DESCRIPTOR statement

DEALLOCATE DESCRIPTOR statement

SET DESCRIPTOR statement

"The SQL descriptor area (SQLDA)"


SET OPTION statement


REVOKE statement


GRANT REMOTE statement

REVOKE CONSOLIDATE statement

GRANT PUBLISH statement

"Granting and revoking REMOTE and CONSOLIDATE permissions",


GRANT REMOTE statement

GRANT CONSOLIDATE statement

REVOKE PUBLISH statement

CREATE PUBLICATION statement

CREATE SUBSCRIPTION statement


GRANT CONSOLIDATE statement

REVOKE REMOTE statement

GRANT PUBLISH statement

"Granting and revoking REMOTE and CONSOLIDATE permissions",


Compound statements

The chapter "Using Procedures, Triggers, and Batches"


OUTPUT statement

INSERT statement

UPDATE statement

DELETE statement

SET OPTION statement


INPUT statement

UPDATE statement

DELETE statement

PUT statement


LOOP statement

FOR statement

Compound statements

The chapter "Using Procedures, Triggers, and Batches"


UNLOAD TABLE statement

INPUT statement


FOR statement

LEAVE statement


CREATE PROCEDURE statement


"Expressions"

"Search conditions"


DECLARE CURSOR statement

PREPARE statement

FETCH statement

RESUME statement

CLOSE statement


SELECT statement


READ statement

"Command Files"


DECLARE CURSOR statement

DESCRIBE statement

OPEN statement

EXECUTE statement

DROP STATEMENT statement


COMMIT statement

ROLLBACK statement


UPDATE statement

UPDATE (positioned) statement

DELETE statement

DELETE (positioned) statement

INSERT statement


PARAMETERS statement


SAVEPOINT statement

ROLLBACK TO SAVEPOINT statement


SIGNAL statement

Compound statements

"Using exception handlers in procedures and triggers"


DECLARE CURSOR statement

"Returning results from procedures"


CREATE FUNCTION statement

CREATE PROCEDURE statement

Compound statements


GRANT statement


GRANT CONSOLIDATE statement


GRANT PUBLISH statement

REVOKE REMOTE statement

CREATE PUBLICATION statement

CREATE SUBSCRIPTION statement


COMMIT statement

ROLLBACK TO SAVEPOINT statement


SAVEPOINT statement

RELEASE SAVEPOINT statement

ROLLBACK statement


CREATE TRIGGER statement

ROLLBACK statement

ROLLBACK TO SAVEPOINT statement

"Transact-SQL RAISERROR statement"


RELEASE SAVEPOINT statement

ROLLBACK TO SAVEPOINT statement


CREATE VIEW statement

DECLARE CURSOR statement

"Expressions"

FETCH statement

FROM clause

OPEN statement

"Search conditions"

UNION operation


CREATE VARIABLE statement

DROP VARIABLE statement

"Expressions"


CONNECT statement

DISCONNECT statement


ALLOCATE DESCRIPTOR statement

DEALLOCATE DESCRIPTOR statement

"The SQL descriptor area (SQLDA)"


CONFIGURE statement

GET OPTION statement

"The database engine"


"Multi-Threaded or Reentrant Code"


RESIGNAL statement

Compound statements

"Using exception handlers in procedures and triggers"


STOP DATABASE statement

CONNECT statement


STOP ENGINE statement

"The database engine"


CREATE SUBSCRIPTION statement

SYNCHRONIZE SUBSCRIPTION statement

"Synchronizing databases",


START DATABASE statement

DISCONNECT statement


START ENGINE statement


CREATE SUBSCRIPTION statement

SYNCHRONIZE SUBSCRIPTION statement

"Synchronizing databases",


CREATE SUBSCRIPTION statement

START SUBSCRIPTION statement

"Synchronizing databases",


COMMIT statement

CONNECT statement


DELETE statement


SELECT statement


LOAD TABLE statement

OUTPUT statement


DELETE statement

INSERT statement

FROM clause


DELETE statement

UPDATE statement


"The Validation utility"


Example for Transact-SQL BEGIN TRANSACTION statement

The following 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


Example for Transact-SQL COMMIT statement

The following 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


Example for Transact-SQL WRITETEXT statement

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 ... ) ;

EXEC SQL writetext table_name.column_name

   textpointer 'newdata' ;


Example for Transact-SQL EXECUTE statement

The following demonstration procedure is used to illustrate the EXECUTE statement.

CREATE PROCEDURE p1( @var INTEGER = 54 )

AS

PRINT 'on input @var = %1! ', @var

DECLARE @internal_var 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.

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


Example for Transact-SQL GOTO statement

The following Transact-SQL batch prints the message "yes" on the engine window four times:

declare @count smallint

select @count = 1

restart:

   print 'yes'

   select @count = @count + 1

   while @count <=4

    goto restart


Example for Transact-SQL IF statement

IF (SELECT max(id) FROM sysobjects) < 100

   RETURN

ELSE

   BEGIN

      PRINT "These are the user-created objects"

      SELECT name, type, id

      FROM sysobjects

      WHERE id < 100

END


Examples for Transact-SQL PRINT statement

♦	The following procedure displays a message on the engine message window:

CREATE PROCEDURE print_test

AS

PRINT 'Procedure called successfully'

The statement

EXECUTE print_test

displays the string Procedure called successfully on the database engine message window.

♦	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


Examples for Transact-SQL RAISERROR statement

The following statement raises error 99999, which is in the range for user-defined errors, and displays a message.

RAISERROR 99999 'Invalid entry for this column: %1!', @val

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.


Example for Transact-SQL WHILE statement

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 $30.


Examples for START USING DATABASE HLI Statement

The following statement starts the sample database on the currently running server or engine server_name:

START USING DATABASE "eng=server_name;dbf=c:\sqlany50\sademo.db"

The following two statements start and then connect to the sample database on the currently running server or engine server_name:

START USING DATABASE "eng=server_name;dbf=c:\sqlany50\sademo.db"

START USING DATABASE server_name:sademo

AS conn1 USER dba IDENTIFIED BY sql


Examples for STOP USING DATABASE HLI Statement

The following statement uses form 1 to disconnect from the current database.

STOP USING DATABASE

The following statement uses form 2 to stop the sample database on the engine server_name:

STOP USING DATABASE "eng=server_name;dbn=sademo"


Example for Backing up a database using the DBTOOL statement

The following statement connects to and backs up the sample database, to directory C:\TEMP.

DBTOOL BACKUP TO 'c:\temp' DBFILE

USING 'dbf=c:\sqlany50\sademo.db;uid=dba;pwd=sql'


Example for Erasing a database using the DBTOOL statement

The following statement erases the database file C:\TEMP.DB and its associated transaction log file, prompting to confirm deletion.

DBTOOL DROP DATABASE 'c:\temp.db'


Example for Obtaining database information using the DBTOOL statement

The following statement gets information about the sample database and puts it in the file C:\TEMP.TXT.

DBTOOL DBINFO DATABASE 'c:\sqlany50\sademo.db'

TO 'c:\temp.txt'

WITH PAGE USAGE

USING 'uid=dba;pwd=sql'


Example for The Open Server Stop utility

The following command stops the Open Server gateway named primeos, using user ID DBA, and password SQL.

dbosstop -S PRIMEOS -U dba -P sql -x thx1138


Example for Uncompressing a database using the DBTOOL statement

The following statement uncompresses the compressed database file C:\TEMP.CDB, creating the database file C:\TEMP.DB

DBTOOL UNCOMPRESS DATABASE 'c:\temp.cdb'


Examples for Connection properties

 To retrieve the value of a connection property:

1	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' )

 To retrieve the values of all connection properties:

1	Use the sa_conn_properties system procedure:

call sa_eng_properties

A separate row is displayed for each connection, for each property.


Examples for Properties available for the engine

 To retrieve the value of an engine property:

1	Use the property system function: The following statement returns the number of cache pages being used to hold the main heap.

select property ( 'MainHeapPages')

 To retrieve the values of all engine properties:

1	Use the sa_eng_properties system procedure:

call sa_eng_properties


Examples for Properties available for each database

 To retrieve the value of a database property:

1	Use the db_property system function: The following statement returns the page size of the current database.

select db_property ( 'PageSize')

 To retrieve the values of all database properties:

1	Use the sa_db_properties system procedure:

call sa_db_properties


Example for ALLOCATE DESCRIPTOR statement

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:\\sqlany50\\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;

   }

   type = DT_STRING;   // change the type to string

   EXEC SQL SET DESCRIPTOR sqlda1 VALUE 2 TYPE = :type;

   fill_sqlda( sqlda1 );  // now we 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;

}


Examples for ALTER DBSPACE statement

Increase the size of the SYSTEM dbspace by 200 pages.

ALTER DBSPACE system

ADD 200

Rename the file for dbspace SYSTEM_2 to dbspace2.

ALTER DBSPACE system_2

RENAME 'e:\db\dbspace2.db'


Example for ALTER PUBLICATION statement

The following statement adds the customer table to the pub_contact publication.

ALTER PUBLICATION pub_contact (

   ADD TABLE customer

)


Example for ALTER REMOTE MESSAGE TYPE statement

The following statement changes the publisher's address for the FILE message link to new_addr.

CREATE REMOTE MESSAGE TYPE file

ADDRESS 'new_addr'


Examples for ALTER TABLE statement

Add a new column to the employees table showing which office they work in.

ALTER TABLE employee

ADD office CHAR(20) DEFAULT 'Boston'

Drop the office column from the employees table.

ALTER TABLE employee

DELETE office

The address column in the customer table can currently hold up to 35 characters. Allow it to hold up to 50 characters.

ALTER TABLE customer

MODIFY address CHAR(50)

Add 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 a 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.


Examples for CALL statement

Call the sp_customer_list procedure. This procedure has no parameters, and returns a result set.

CALL sp_customer_list()

The following ISQL 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.

% Set the statement delimiter to create the procedure

SET OPTION COMMAND_DELIMITER = ';;'

% Create the procedure

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 ;;

% Reset the statement delimiter to semicolon.

SET OPTION COMMAND_DELIMITER = ';'

% Create a variable to hold the result

CREATE VARIABLE Orders INT ;

% Call the procedure, FOR customer 101

%-----------------------------

CALL OrderCount ( 101, Orders) ;

%------------------------------

% Display the result

SELECT Orders FROM DUMMY ;


Example for CASE statement

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.

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


Examples for CLOSE statement

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


Examples for COMMENT statement

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


Example for Compound statements

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


Examples for CONNECT statement

♦	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 are examples of CONNECT usage from ISQL.

♦	Connect to a database from ISQL. ISQL will prompt for a user ID and a password.

CONNECT

♦	Connect to the default database as DBA, from ISQL. ISQL will prompt for a password.

CONNECT USER "DBA"

♦	Connect to the sample database as the DBA, from ISQL.

CONNECT

TO sademo

USER "DBA"

IDENTIFIED BY sql

♦	Connect to the sample database using a connect string, from ISQL.

CONNECT

USING 'UID=DBA;PWD=sql;DBN=sademo'


Example for CREATE DATATYPE statement

The following statement creates a data type named address, which holds a 35-character string, and which may be NULL.

CREATE DATATYPE 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 DATATYPE id INT

NOT NULL

DEFAULT AUTOINCREMENT


Example for CREATE DBSPACE statement

Create a dbspace called library to hold the LibraryBooks table and its indices.

CREATE DBSPACE library

AS 'e:\dbfiles\library.db' ;

CREATE TABLE LibraryBooks (

title char(100),

author char(50),

isbn char(30),

) IN library ;


Example for CREATE FUNCTION statement

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 ISQL statements 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

Robert Breault

...


Examples for CREATE INDEX statement

♦	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 product ID column.

CREATE INDEX item_prod

ON sales_order_items

( prod_id )


Example for CREATE PROCEDURE statement

♦	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


Example for CREATE PUBLICATION statement

CREATE PUBLICATION pub_contact (

TABLE contact

)


Example for CREATE REMOTE MESSAGE TYPE statement

When remote databases are extracted using the extraction utility, the following statement sets all recipients of FILE messages to send messages back to the company subdirectory of the SQLREMOTE environment variable.

The statement also instructs DBREMOTE to look in the COMPANY subdirectory for incoming messages.

CREATE REMOTE MESSAGE TYPE file

ADDRESS 'company'


Examples for CREATE SCHEMA statement

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 engine.  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 ) ;


Example for CREATE SUBSCRIPTION statement

CREATE SUBSCRIPTION TO pub_sales ( 'Eastern' )

FOR p_chin


Examples for Integrity constraints

The first two examples are for a library database.

Create 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

-- will be created

FOREIGN KEY location REFERENCES room

)

Create a table for a library database to hold information on borrowed books.

CREATE TABLE borrowed_book (

-- Default on insert is that book is borrowed today

date_borrowed DATE NOT NULL DEFAULT CURRENT DATE,

-- date_returned will be NULL until the book is returned

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 is for a sales database.

Create 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

)


Example for CREATE TRIGGER statement

♦	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


Example for CREATE VARIABLE statement

♦	The following code fragment could be used to insert a large text value into the database.

EXEC SQL BEGIN DECLARE SECTION;

char buffer[5000];

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;

   /* add data to blob using concatenation

   Note that concatenation works for binary

   data too! */

   EXEC SQL SET hold_blob = hold_blob || :buffer;

}

EXEC SQL INSERT INTO some_table VALUES ( 1, hold_blob );

EXEC SQL DROP VARIABLE hold_blob;


Examples for CREATE VIEW statement

Create a view showing all 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'

Create 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


Examples for Declaration section

EXEC SQL BEGIN DECLARE SECTION;

char *emp_lname, initials[5];

int dept;

EXEC SQL END DECLARE SECTION;


Embedded SQL Examples for DECLARE CURSOR statement

1. EXEC SQL DECLARE cur_employee SCROLL CURSOR FOR

SELECT * FROM employee ;

2. EXEC SQL PREPARE employee_statement

FROM 'SELECT emp_lname FROM employee' ;

EXEC SQL DECLARE cur_employee CURSOR FOR employee_statement ;


Procedure/trigger Example for DECLARE CURSOR statement

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


Embedded SQL Example for DECLARE TEMPORARY TABLE statement

1. EXEC SQL DECLARE LOCAL TEMPORARY TABLE MyTable (

      number INT

   );


Procedure/trigger Example for DECLARE TEMPORARY TABLE statement

BEGIN

   DECLARE LOCAL TEMPORARY TABLE TempTab (

         number INT

   );

   ...

END


Example for DEALLOCATE DESCRIPTOR statement

For an example, see "ALLOCATE DESCRIPTOR statement".


Examples for DELETE statement

Remove employee 105 from the database.

DELETE

FROM employee

WHERE emp_id = 105

Remove all data prior to 1993 from the fin_data table.

DELETE

FROM fin_data

WHERE year < 1993

Remove all names from the contact table if they are already present in the customer table.

DELETE

FROM contact

FROM contact, customer

WHERE contact.last_name = customer.lname

AND contact.first_name = customer.fname


Example for DELETE (positioned) statement

♦	The following statement removes the current row from the database.

DELETE

WHERE CURRENT OF cur_employee


Example for 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;

}


Embedded SQL Example for DISCONNECT statement

EXEC SQL DISCONNECT :conn_name


ISQL Example for DISCONNECT statement

DISCONNECT ALL


Examples for DROP statement

Drop the department table from the database.

DROP TABLE department

Drop the emp_dept view from the database.

DROP VIEW emp_dept


Example for DROP CONNECTION statement

The following statement drops connection with ID number 4.

DROP CONNECTION 4


Example for DROP PUBLICATION statement

DROP PUBLICATION pub_contact


Example for DROP REMOTE MESSAGE TYPE statement

The following statement drops the FILE message type from a database.

DROP REMOTE MESSAGE TYPE file


Example for DROP STATEMENT statement

1. EXEC SQL DROP STATEMENT S1;

2. EXEC SQL DROP STATEMENT :stmt;


Example for DROP SUBSCRIPTION statement

The following statement drops a subscription for the user ID SamS to the publication pub_contact.

DROP SUBSCRIPTION TO pub_contact

FOR SamS


Examples for EXECUTE statement

1. EXEC SQL EXECUTE IMMEDIATE

'DELETE FROM employee WHERE emp_id = 105';

2. EXEC SQL PREPARE del_stmt FROM

'DELETE FROM employee WHERE emp_id = :a';

EXEC SQL EXECUTE del_stmt USING :employee_number;

3. EXEC SQL PREPARE sel1 FROM

'SELECT emp_lname FROM employee WHERE emp_id = :a';

EXEC SQL EXECUTE sel1 USING :employee_number INTO :emp_lname;


Example for EXECUTE IMMEDIATE statement

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 if you run this example.

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 mytable:

CALL CreateTableProc( 'mytable' )


Examples for EXPLAIN statement

EXEC SQL BEGIN DECLARE SECTION;

char plan[300];

EXEC SQL END DECLARE SECTION;

EXEC SQL DECLARE employee_cursor CURSOR FOR

   SELECT empnum, empname

   FROM employee

   WHERE name like :pattern;

EXEC SQL OPEN employee_cursor;

EXEC SQL EXPLAIN PLAN FOR CURSOR employee_cursor INTO :plan;

printf( "Optimization Strategy: '%s'.n", plan );


Embedded SQL Example for FETCH statement

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;

For a detailed example of using wide fetches, see the section "Fetching more than one row at a time".


Procedure/trigger Example for FETCH statement

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

LOOP statement, DECLARE CURSOR statement, FETCH statement, LEAVE statement


Example for FOR statement

FOR names AS curs CURSOR FOR

SELECT emp_lname

FROM employee

DO

   CALL search_for_name( emp_lname );

END FOR;


Examples for Join abbreviations

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


Example for GET DATA statement

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;

long offset;

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;


Example for GET DESCRIPTOR statement

For an example, see "ALLOCATE DESCRIPTOR statement".


Example for GET OPTION statement

EXEC SQL GET OPTION 'date_format' INTO :datefmt;


Examples for GRANT statement

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

Allow the user Hardy to execute the Calculate_Report procedure.

GRANT

EXECUTE ON Calculate_Report

TO Hardy


Example for GRANT CONSOLIDATE statement

GRANT CONSOLIDATE TO con_db

TYPE mapi

ADDRESS 'Consolidated Database'


Example for GRANT PUBLISH statement

GRANT PUBLISH TO publisher_ID


Example for GRANT REMOTE statement

GRANT REMOTE TO SamS

TYPE mapi

ADDRESS 'Singer, Samuel'


Example for 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


Example for INPUT statement

The following is an example of an INPUT statement from an ASCII text file.

INPUT INTO employee

FROM new_emp.inp

FORMAT ascii;


Examples for INSERT statement

Add an Eastern Sales department to the database.

INSERT

INTO department ( dept_id, dept_name )

VALUES ( 230, 'Eastern Sales' )

Fill the table dept_head with the names of department heads and their departments.

INSERT

INTO dept_head (name, dept)

SELECT emp_fname || ' ' || emp_fname

         AS name,

      dept_name

FROM employee JOIN department

ON emp_id = dept_head_id


Examples for LEAVE statement

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


Examples for LOOP statement

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


Example for MESSAGE statement

The following procedure displays a message on the engine message window:

CREATE PROCEDURE message_test ()

BEGIN

MESSAGE 'procedure called successfully' ;

END

The statement

CALL message_test()

displays the string procedure called successfully on the database engine message window.


Example for NULL value

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' )


Examples for OPEN statement

The following examples show the use of OPEN in Embedded SQL.

1. EXEC SQL OPEN employee_cursor;

2. 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;


Procedure/trigger Example for OPEN statement

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


Example for OUTPUT statement

Place the contents of the employee table in a file, in ASCII format.

SELECT *

FROM employee ;

OUTPUT TO employee.txt

FORMAT ASCII


Example for PARAMETERS statement

The following ISQL command file takes two parameters.

PARAMETERS department_id, file ;

SELECT emp_lname

FROM employee

WHERE dept_id = {department_id}

>#{file}.dat;


Example for PASSTHROUGH statement

PASSTHROUGH FOR rem_db ;

...

( SQL statements to be executed at the remote database )

...

PASSTHROUGH STOP ;


Example for PREPARE statement

EXEC SQL PREPARE employee_statement FROM

'SELECT * from employee';


Examples for PREPARE TO COMMIT statement

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 allows the delete to take place, even though it causes integrity violations. The PREPARE TO COMMIT statement causes an error reporting the violation.

SET OPTION wait_for_commit= 'ON' ;

DELETE

FROM department

WHERE dept_id = 100 ;

PREPARE TO COMMIT ;


Example for PUT statement

EXEC SQL PUT cur_employee FROM :emp_id, :emp_lname;


Examples for READ statement

The following are examples of the READ statement.

READ status.rpt '160'

READ birthday.sql [>= '1988-1-1'] [<= '1988-1-30']


Example for RESIGNAL statement

The following fragment returns all exceptions except for 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 ;


Examples for RESUME statement

Embedded SQL example

1. EXEC SQL RESUME cur_employee;

2. EXEC SQL RESUME :cursor_var;

ISQL examples

CALL sample_proc() ;

RESUME ALL;


Example for RETURN statement

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


Examples for REVOKE statement

Prevent user Dave from updating the employee table.

REVOKE UPDATE ON employee FROM dave ;

Revoke resource permissions from user Jim.

REVOKE RESOURCE FROM Jim ;

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


Example for REVOKE CONSOLIDATE statement

REVOKE CONSOLIDATE FROM condb


Example for REVOKE PUBLISH statement

REVOKE PUBLISH FROM publisher_ID


Example for REVOKE REMOTE statement

REVOKE REMOTE FROM SamS


Embedded SQL Example for SELECT statement

SELECT count(*) INTO :size FROM employee


Examples for SELECT statement

List all the tables and views in the system catalog.

SELECT tname

FROM SYS.SYSCATALOG

WHERE tname LIKE 'SYS%' ;

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

   LEFT OUTER JOIN sales_order

   LEFT OUTER JOIN sales_order_items

   LEFT OUTER JOIN product

GROUP BY company_name

ORDER BY VALUE DESC

How many employees are there?

SELECT count(*)

FROM Employee ;


Example for SET statement

♦	The following code fragment could be used to insert a large text value into the database.

EXEC SQL BEGIN DECLARE SECTION;

char buffer[5001];

EXEC SQL END DECLARE SECTION;

EXEC SQL CREATE VARIABLE hold_text LONG VARCHAR;

EXEC SQL SET hold_text = '';

for(;;) {

   /* read some data into buffer ... */

   size = fread( buffer, 1, 5000, fp );

   if( size <= 0 ) break;

   /* buffer must be null-terminated */

   buffer[size] = '\0';

   /* add data to blob using concatenation */

   EXEC SQL SET hold_text = hold_text || :buffer;

}

EXEC SQL INSERT INTO some_table VALUES ( 1, hold_text );

EXEC SQL DROP VARIABLE hold_text;

♦	The following code fragment could be used to insert 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

      Note that concatenation works for

      binary data too! */

   EXEC SQL SET hold_blob = hold_blob || :buffer;

}

EXEC SQL INSERT INTO some_table VALUES ( 1, hold_blob );

EXEC SQL DROP VARIABLE hold_blob;


Example for SET CONNECTION statement

The following example is in Embedded SQL.

EXEC SQL SET CONNECTION :conn_name;


Example for SET CONNECTION statement

From ISQL, set the current connection to the connection named conn1.

SET CONNECTION conn1 ;


Example for SET DESCRIPTOR statement

For an example, see "ALLOCATE DESCRIPTOR statement".


Examples for ISQL options

Set the date format option.

SET OPTION public.date_format = 'Mmm dd yyyy' ;

Set the 'wait for commit' option to on.

SET OPTION waitefor_commit = 'on' ;


Embedded SQL Examples for ISQL options

1. EXEC SQL SET OPTION :user.:option_name = :value;

2. EXEC SQL SET TEMPORARY OPTION Date_format = 'mm/dd/yyyy';


Example for SET SQLCA statement

The following 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 );

}


Example for START DATABASE statement

Start the database file C:\SQLANY50\SAMPLE_2.DB on the current engine.

start database 'c:\sqlany50\sample_2.db'

Start the database file C:\SQLANY50\SAMPLE_2.DB as sam2 on the engine named sample.

START DATABASE 'c:\sqlany50\sample_2.db'

AS sam2

ON sample ;


Example for START ENGINE statement

Start a database engine, named sample, without starting any databases on it.

START ENGINE AS sample ;

Start a database engine with a maximum cache size of 4 megabytes, loading the sample database.

START ENGINE AS sample

STARTLINE 'dbeng50w -c 4096 c:\sqlany50\sademo.db'

The following example shows the use of a STARTLINE clause.

START ENGINE AS eng1 STARTLINE 'dbeng50 -c 8096'


Example for START SUBSCRIPTION statement

The following statement starts the subscription of user SamS to the pub_contact publication.

START SUBSCRIPTION TO pub_contact

FOR SamS


Examples for STOP DATABASE statement

Stop the database named sample on the default engine.

STOP DATABASE sample ;


Example for STOP ENGINE statement

Stop the database engine named sample.

STOP ENGINE sample


Example for STOP SUBSCRIPTION statement

The following statement starts the subscription of user SamS to the pub_contact publication.

STOP SUBSCRIPTION TO pub_contact

FOR SamS


Example for SYNCHRONIZE SUBSCRIPTION statement

The following statement synchronizes the subscription of user SamS to the pub_contact publication.

SYNCHRONIZE SUBSCRIPTION TO pub_contact

FOR SamS


Example for SYSTEM statement

SYSTEM date


Example for TRUNCATE TABLE statement

Delete all rows from the department table.

TRUNCATE TABLE department


Examples for UNION operation

List all distinct surnames of employees and customers.

SELECT emp_lname

FROM Employee

UNION

SELECT lname

FROM Customer ;


Examples for UPDATE statement

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_items AS items ,

sales_order AS orders

SET items.id = items.id - 2000,

orders.id = orders.id - 2000 ;


Example for UPDATE (positioned) statement

UPDATE Employee

SET emp_lname = 'Jones'

WHERE CURRENT OF emp_cursor ;


Examples for WHENEVER statement

The following are examples of the WHENEVER statement:

EXEC SQL WHENEVER NOTFOUND GOTO done;

EXEC SQL WHENEVER SQLERROR

{ PrintError( &sqlca ); return( FALSE ); };


Examples for Catalog stored procedures

♦	The following statement returns a single row describing the current database:

call sa_db_info

Sample values are as follows:

Property	Value
Number	0
Alias	sademo
File	c:\sqlany50\sademo.db
ConnCount	1
PageSize	1024
LogName	c:\sqlany50\sademo.log
♦	The following statement returns a set of available engine properties

call sa_eng_properties()

PropNum	PropName	...
0	IdleCheck	...
1	IdleWrite	...
2	IdleChkPt	...
...	...	...


Example for xp_sendmail system procedure

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'

      )


Example for xp_cmdshell system procedure

The following statement lists the files in the current directory in the file C:\TEMP.TXT

xp_cmdshell('dir > c:\\temp.txt')


Example for xp_msver system function

♦	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
5.5.02 (1438)	Sybase SQL Anywhere Windows NT


Example for xp_sprintf system procedure

The following statements put the string Hello World! into the variable mystring.

CREATE VARIABLE mystring CHAR(254) ;

xp_sprintf( mystring, 'Hello %s', 'World!' )


Example for xp_scanf system procedure

The following statements put the string World! into the variable mystring.

CREATE VARIABLE mystring CHAR(254) ;

xp_scanf( 'Hello World!', 'Hello %s', mystring )