Академический Документы
Профессиональный Документы
Культура Документы
iii
4 ODBC Programming...................................................... 127
Introduction to ODBC programming ..................................... 128
ODBC fundamentals ............................................................. 130
Error checking....................................................................... 133
Using prepared statements................................................... 135
Working with result sets ........................................................ 137
Calling stored procedures ..................................................... 139
A sample program................................................................. 141
Using ODBC without the driver manager.............................. 143
Using ODBC on Windows CE............................................... 145
Index............................................................................... 171
iv
About This Manual
Subject
This manual describes the programming interfaces available for Adaptive
Server Anywhere.
Audience This manual is intended for application developers writing programs that
work directly with one of the Adaptive Server Anywhere interfaces.
You do not need to read this manual if you are using a development tool,
such as Powersoft PowerBuilder or Power++, which has its own database
interface on top of ODBC.
Contents
Topic Page
Related documentation vi
Documentation conventions vii
The sample database x
v
Related documentation
Adaptive Server Anywhere is a part of SQL Anywhere Studio. For an
overview of the different components of SQL Anywhere Studio, see
Introducing SQL Anywhere Studio.
The Adaptive Server Anywhere documentation consists of the following
books:
♦ Getting Started Intended for all users of Adaptive Server Anywhere,
this book describes the following:
♦ New features in Adaptive Server Anywhere
♦ Behavior changes from previous releases
♦ Upgrade procedures
♦ Introductory material for beginning users.
♦ User’s Guide A comprehensive guide to using SQL, administering
databases, and using Adaptive Server Anywhere features.
♦ Reference A full reference to Adaptive Server Anywhere. This book
describes the database server, the administration utilities, the SQL
language, and error messages.
♦ Quick Reference A handy printed booklet with complete SQL syntax
and other key reference material in a concise format.
♦ Read Me First (UNIX only) A separate booklet is provided with UNIX
versions of Adaptive Server Anywhere, describing installation and
adding some UNIX-specific notes.
The format of these books (printed or online) may depend on the product in
which you obtained Adaptive Server Anywhere. Depending on which
package you have purchased, you may have additional books describing
other components of your product.
vi
Documentation conventions
This section lists the typographic and graphical conventions used in this
documentation.
Syntax conventions
The following conventions are used in the SQL syntax descriptions:
♦ Keywords All SQL keywords are shown in UPPER CASE. However,
SQL keywords are case insensitive, so you can enter keywords in any
case you wish; SELECT is the same as Select which is the same as
select.
♦ Placeholders Items that must be replaced with appropriate identifiers
or expressions are shown in italics.
♦ Continuation Lines beginning with ... are a continuation of the
statements from the previous line.
♦ Repeating items Lists of repeating items are shown with an element
of the list followed by an ellipsis (three dots). One or more list elements
are allowed. 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. The square brackets
should not be typed.
♦ Options When none or only one of a list of items must be chosen, the
items are separated by vertical bars and the list enclosed in square
brackets.
For example, …
[ ASC | DESC ]
… indicates that you can choose one of ASC, DESC, or neither. The
square brackets should not be typed.
♦ Alternatives When precisely one of the options must be chosen, the
alternatives are enclosed in curly braces. For example …
QUOTES { ON | OFF }
… indicates that exactly one of ON or OFF must be provided. The
braces should not be typed.
vii
Graphic icons
The following icons are used in this documentation:
Icon Meaning
A client application.
If the icon is used to represent a particular application
or kind of application, the name is indicated in the
bottom right corner.
A database.
In some high-level diagrams, the icon may be used to
represent both the database and the database server
that manages it.
viii
Installed files
The following terms are used throughout the manual:
♦ Installation directory The directory into which you install Adaptive
Server Anywhere.
♦ Executable directory The executables and other files for each
operating system are held in an executable subdirectory of the
installation directory. This subdirectory has the following name:
♦ Windows NT and Windows 95/98 win32
♦ UNIX bin
♦ Windows 3.x win
♦ NetWare and Windows CE The executables are held in the
Adaptive Server Anywhere installation directory itself on these
platforms.
ix
The sample database
There is a sample database included with Adaptive Server Anywhere. Many
of the examples throughout the documentation use this sample database.
The sample database represents a small company. It contains internal
information about the company (employees, departments, and financial data)
as well as product information (products), sales information (sales orders,
customers, and contacts), and financial information (fin_code, fin_data).
The following figure shows the tables in the sample database and how they
are related to each other.
asademo.db
product employee
id <pk> integer sales_order_items
emp_id <pk> integer
name char(15) id <pk,fk> integer
manager_id integer
description char(30) line_id <pk> smallint
emp_fname char(20)
size char(18) id = prod_id prod_id <fk> integer
emp_lname char(20)
color char(6) quantity integer
dept_id <fk> integer
quantity integer ship_date date
street char(40)
unit_price numeric(15,2)
city char(20)
state char(4)
id = id
emp_id = sales_rep zip_code char(9)
phone char(10)
customer status char(1)
ss_number char(11)
id <pk> integer sales_order
salary numeric(20,3)
fname char(15) id <pk> integer start_date date
lname char(20) cust_id <fk> integer termination_date date
address char(35) order_date date birth_date date
city char(20) id = cust_id fin_code_id <fk> char(2) bene_health_ins char(1)
state char(2) region char(7) bene_life_ins char(1)
zip char(10) sales_rep <fk> integer bene_day_care char(1)
phone char(12)
sex char(1)
company_name char(35) code = fin_code_id
fin_code
code <pk> char(2)
contact dept_id = dept_id
type char(10)
id <pk> integer description char(50) emp_id = dept_head_id
last_name char(15)
first_name char(15)
title char(2) code = code
street char(30)
city char(20) fin_data
state char(2) year <pk> char(4) department
zip char(5) quarter <pk> char(2) dept_id <pk> integer
phone char(10) code <pk,fk> char(2) dept_name char(40)
fax char(10) amount numeric(9) dept_head_id <fk> integer
x
C H A P T E R 1
About this chapter This chapter provides an introductory overview of each of the programming
interfaces for Adaptive Server Anywhere. Any client application uses one of
these interfaces to communicate with the database, and this chapter provides
some guidelines to help you choose an appropriate interface for your
application.
Contents
Topic Page
The ODBC programming interface 2
The Embedded SQL programming interface 3
The JDBC programming interface 4
The Open Client programming interface 5
Before you begin $ For an introduction to some aspects of database programming, see
"Using SQL in Applications" on page 257 of the book ASA User’s Guide.
1
The ODBC programming interface
2
Chapter 1 Programming Interface Overview
3
The JDBC programming interface
4
Chapter 1 Programming Interface Overview
5
The Open Client programming interface
6
C H A P T E R 2
About this chapter This chapter describes the Embedded SQL programming interface to
Adaptive Server Anywhere.
Contents
Topic Page
Application development using Embedded SQL 8
Embedded SQL data types 17
Using host variables 20
The SQL Communication Area 27
Fetching data 32
Static and dynamic SQL 40
The SQL descriptor area (SQLDA) 44
Using stored procedures in Embedded SQL 52
Library functions 56
Embedded SQL commands 72
Database examples 74
The SQL preprocessor 79
7
Application development using Embedded SQL
Supported compilers
The C language SQL preprocessor has been used in conjunction with the
following compilers:
8
Chapter 2 The Embedded SQL Interface
C Source Code
SQL
Preprocessor
C Compiler
Custom
DLL
Application Database
9
Application development using Embedded SQL
Filename Description
sqlca.h Main header file included in all Embedded SQL programs. This
file includes the structure definition for the SQL Communication
Area (SQLCA) and prototypes for all Embedded SQL database
interface functions.
sqlda.h SQL Descriptor Area structure definition included in Embedded
SQL programs that use dynamic SQL.
sqldef.h Definition of Embedded SQL interface data types. This file also
contains structure definitions and return codes needed for starting
the database server from a C program.
sqlerr.h Definitions for error codes returned in the sqlcode field of the
SQLCA.
sqlstate.h Definitions for ANSI/ISO SQL standard error states returned in
the sqlstate field of the SQLCA.
pshpk1.h, These headers ensure that structure packing is handled correctly.
pshpk2.h, They support Watcom C/C++, Microsoft Visual C++, IBM
poppk.h Visual Age, and Borland C/C++ compilers.
10
Chapter 2 The Embedded SQL Interface
Import libraries
All import libraries are installed in the lib subdirectory, under the operating
system subdirectory of the Adaptive Server Anywhere installation directory.
For example, Windows 95/98 and Windows NT import libraries are stored in
the win32\lib subdirectory.
The libdbtasks6 libraries are called by the libdblib6 library. Some compilers
locate libdbtasks6 automatically, while for others you need to specify it
explicitly.
A simple example
The following is a very simple example of an Embedded SQL program.
#include <stdio.h>
EXEC SQL INCLUDE SQLCA;
main()
{
db_init( &sqlca );
EXEC SQL WHENEVER SQLERROR GOTO error;
11
Application development using Embedded SQL
error:
printf( "update unsuccessful -- sqlcode = %ld.n",
sqlca.sqlcode );
db_fini( &sqlca );
return( -1 );
}
This example connects to the database, updates the surname of employee
number 195, commits the change and exits. There is virtually no interaction
between the SQL and C code. The only thing the C code is used for in this
example is control flow. The WHENEVER statement is used for error
checking. The error action (GOTO in this example) is executed after any
SQL statement that causes an error.
Note that the first section of this chapter uses UPDATE and INSERT
examples because they are simpler.
$ For a description of fetching data, see "Fetching data" on page 32.
12
Chapter 2 The Embedded SQL Interface
Macro Platforms
_SQL_OS_WINNT Windows 95/98, Windows CE,
and Windows NT
_SQL_OS_UNIX UNIX
_SQL_OS_UNIX NetWare
4 Compile esqldll.c.
5 Instead of linking against the imports library, link the object module
esqldll.obj with your Embedded SQL application objects.
Example The following example illustrates how to use esqldll.c and esqldll.h.
13
Application development using Embedded SQL
#include <stdio.h>
#include "esqldll.h"
14
Chapter 2 The Embedded SQL Interface
#ifdef _SQL_OS_WINNT
result = db_string_connect( &sqlca,
"UID=dba;PWD=sql;DBF=d:\\asa6\\sample.db");
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 );
15
Application development using Embedded SQL
free_filled_sqlda( sqlda1 );
db_string_disconnect( &sqlca, "" );
db_fini( &sqlca );
db_fini_dll();
return( 0 );
}
16
Chapter 2 The Embedded SQL Interface
17
Embedded SQL data types
18
Chapter 2 The Embedded SQL Interface
19
Using host variables
20
Chapter 2 The Embedded SQL Interface
21
Using host variables
Pointers to char A host variable declared as a pointer to char (char *a) is considered by the
database interface to be 32,767 bytes long. Any host variable of type pointer
to char used to retrieve information from the database must point to a buffer
large enough to hold any value that could possibly come back from the
database.
This is potentially quite dangerous, because somebody could change the
definition of the column in the database to be larger than it was when the
program was written. This could cause random memory corruption problems.
If you are using a 16-bit compiler, requiring 32,767 bytes could make the
program stack overflow. It is better to use a declared array, even as a
parameter to a function where it is passed as a pointer to char. This lets the
PREPARE statements know the size of the array.
Scope of host A standard host-variable declaration section can appear anywhere that C
variables 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
Indicator variables
Indicator variables are C variables that hold supplementary information when
you are fetching or putting data. There are several distinct uses for indicator
variables:
♦ NULL values To enable applications to handle NULL values.
♦ String truncation To enable applications to handle cases when fetched
values must be truncated to fit into host variables.
23
Using host variables
/*
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 );
24
Chapter 2 The Embedded SQL Interface
If the indicator variable has a value of –1, a NULL is written. If it has a value
of 0, the actual value of employee_phone is written.
Using indicator Indicator variables are also used when receiving data from the database.
variables when They are used to indicate that a NULL value was fetched (indicator is
fetching NULL negative). If a NULL value is fetched from the database and an indicator
variable is not supplied, an error is generated (SQLE_NO_INDICATOR).
Errors are explained in the next section.
25
Using host variables
26
Chapter 2 The Embedded SQL Interface
27
The SQL Communication Area
sqlerror array The sqlerror field array has the following elements.
♦ sqlerrd[1] (SQLIOCOUNT) The actual number of input/output
operations that were required to complete a command.
The database does not start this number at zero for each command. Your
program can set this variable to zero before executing a sequence of
commands. After the last command, this number is the total number of
input/output operations for the entire command sequence.
♦ sqlerrd[2] (SQLCOUNT) The value of this field depends on which
statement is being executed.
♦ INSERT, UPDATE, PUT, and DELETE statements The number
of rows that were affected by the statement.
On a cursor OPEN, this field is filled in with either the actual
number of rows in the cursor (a value greater than or equal to 0) or
an estimate thereof (a negative number whose absolute value is the
estimate). It is the actual number of rows if the database server can
compute it without counting the rows. The database can also be
configured to always return the actual number of rows using the
ROW_COUNT option.
28
Chapter 2 The Embedded SQL Interface
29
The SQL Communication Area
Caution
Failure to call db_fini for each db_init on NetWare can cause the
database server to fail, and the NetWare file server to fail.
30
Chapter 2 The Embedded SQL Interface
The following list details the environments where multiple SQLCAs must be
used:
♦ Multi-threaded applications If more than one thread uses the same
SQLCA, a context switch can cause more than one thread to be using the
SQLCA at the same time. Each thread must have its own SQLCA. This
can also happen when you have a DLL that uses Embedded SQL and is
called by more than one thread in your application.
♦ Dynamic link libraries and shared libraries A DLL has only one
data segment. While the database server is processing a request from one
application, it may yield to another application that makes a request to
the database server. If your DLL uses the global SQLCA, both
applications are using it at the same time. Each Windows application
must have its own SQLCA.
♦ A DLL with one data segment A DLL can be created with only one
data segment or one data segment for each application. If your DLL has
only one data segment, you cannot use the global SQLCA for the same
reason, that a DLL cannot use the global SQLCA. Each application must
have its own SQLCA.
Record locking
Operations on different connections are subject to the normal record
locking mechanisms and may cause each other to block and possibly to
deadlock. For information on locking, see the chapter "Using Transactions
and Isolation Levels" on page 369 of the book ASA User’s Guide.
31
Fetching data
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.
Embedded SELECT
A single row query retrieves at most one row from the database. A single-
row query SELECT statement has an INTO clause following the select list
and before the FROM clause. The INTO clause contains a list of host
variables to receive the value for each select list item. There must be the
same number of host variables as there are select list items. The host
variables may be accompanied by indicator variables to indicate NULL
results.
When the SELECT statement is executed, the database server retrieves the
results and places them in the host variables. If the query results contain
more than one row, the database server returns an error.
If the query results in no rows being selected, a Row Not Found warning is
returned. Errors and warnings are returned in the SQLCA structure, as
described in "The SQL Communication Area" on page 27.
Example For example, the following code fragment returns 1 if a row from the
employee table is successfully fetched, 0 if the row doesn’t exist and –1 if an
error occurs.
EXEC SQL BEGIN DECLARE SECTION;
long 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 ) {
32
Chapter 2 The Embedded SQL Interface
33
Fetching data
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;
}
34
Chapter 2 The Embedded SQL Interface
1 –n
2 –n + 1
3 –n + 2
n–2 –3
n–1 –2
n –1
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"
on page 509 of the book ASA Reference ). It can be positioned to an absolute
position either from the start or from the end of the query results. It can also
be moved relative to the current cursor position.
There are special positioned versions of the UPDATE and DELETE
statements that can be used to update or delete the row at the current position
of the cursor. If the cursor is positioned before the first row or after the last
row, a No Current Row of Cursor error is returned.
The PUT statement can be used to insert a row into a cursor.
Cursor positioning Inserts and some updates to DYNAMIC SCROLL cursors can cause
problems problems with cursor positioning. The database server does not put inserted
rows at a predictable position within a cursor unless there is an ORDER BY
clause on the SELECT statement. In some cases, the inserted row does not
appear at all until the cursor is closed and opened again.
With Adaptive Server Anywhere, this occurs if a temporary table had to be
created to open the cursor (see "Temporary tables used in query processing"
on page 802 of the book ASA User’s Guide for a description).
The UPDATE statement may cause a row to move in the cursor. This
happens if the cursor has an ORDER BY clause that uses an existing index (a
temporary table is not created).
35
Fetching data
36
Chapter 2 The Embedded SQL Interface
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 );
}
rows = 0L;
FetchWidth = 20;
stmt = qry;
EXEC SQL PREPARE :stat FROM :stmt;
37
Fetching data
for( ;; ) {
EXEC SQL FETCH QCURSOR INTO DESCRIPTOR sqlda
ARRAY :FetchWidth;
if (SQLCODE != SQLE_NOERROR) break;
if( SQLCOUNT == 0 ) {
rows += 1;
} else {
rows += SQLCOUNT;
}
}
err:
if (SQLCODE != SQLE_NOERROR) {
printf( "Error detected\n" );
}
return (SQLCODE);
}
Notes on using ♦ In the function PrepareSQLDA, the SQLDA memory is allocated using
wide fetches the alloc_sqlda function. This allows space for indicator variables,
rather than using the alloc_sqlda_noind function.
♦ If the number of rows fetched is fewer than the number requested, but is
not zero (at the end of the cursor for example), the SQLDA items
corresponding to the rows that were not fetched are returned as NULL
by setting the indicator value. If no indicator variables are present, an
error is generated (SQLE_NO_INDICATOR: no indicator variable for
NULL result).
38
Chapter 2 The Embedded SQL Interface
39
Static and dynamic SQL
40
Chapter 2 The Embedded SQL Interface
A place holder is put in the statement to indicate where host variables are to
be accessed. A place holder is either a question mark (?) or a host variable
reference as in static statements (a host variable name preceded by a colon).
In the latter case, the host variable name used in the actual text of the
statement serves only as a place holder indicating a reference to the SQL
descriptor area.
A host variable used to pass information to the database is called a bind
variable.
Example For example:
EXEC SQL BEGIN DECLARE SECTION;
char comm[200];
char address[30];
char city[20];
short int cityind;
long empnum;
EXEC SQL END DECLARE SECTION;
. . .
sprintf( comm, "update %s set address = :?,
city = :?"
" where employee_number = :?",
tablename );
EXEC SQL PREPARE S1 FROM :comm;
EXEC SQL EXECUTE S1 USING :address, :city:cityind,
:empnum;
This method requires the programmer to know how many host variables
there are in the statement. Usually, this is not the case. So, you can set up
your own SQLDA structure and specify this SQLDA in the USING clause
on the EXECUTE command.
The DESCRIBE BIND VARIABLES statement returns the host variable
names of the bind variables that are found in a prepared statement. This
makes it easier for a C program to manage the host variables. The general
method is as follows:
EXEC SQL BEGIN DECLARE SECTION;
char comm[200];
EXEC SQL END DECLARE SECTION;
. . .
sprintf( comm, "update %s set address = :address,
city = :city"
" where employee_number = :empnum",
tablename );
EXEC SQL PREPARE S1 FROM :comm;
/* Assume that there are no more than 10 host variables.
See next example if you can’t put
a limit on it */
sqlda = alloc_sqlda( 10 );
41
Static and dynamic SQL
SQLDA contents The SQLDA consists of an array of variable descriptors. Each descriptor
describes the attributes of the corresponding C program variable, or the
location that the database stores data into or retrieves data from:
♦ data type
♦ length if type is a string type
♦ precision and scale if type is a numeric type
♦ memory address
♦ indicator variable
$ For a complete description of the SQLDA structure, see "The SQL
descriptor area (SQLDA)" on page 44
Indicator variables The indicator variable is used to pass a NULL value to the database or
and NULL retrieve a NULL value from the database. The indicator variable is also used
by the database server to indicate truncation conditions encountered during a
database operation. The indicator variable is set to a positive value when not
enough space was provided to receive a database value.
$ For more information, see "Indicator variables" on page 23.
42
Chapter 2 The Embedded SQL Interface
. . .
sprintf( comm, "select * from %s", table_name );
EXEC SQL PREPARE S1 FROM :comm;
/* Initial guess of 10 columns in result. If it is
wrong, it is corrected right after the first
DESCRIBE by reallocating sqlda and doing DESCRIBE
again. */
sqlda = alloc_sqlda( 10 );
EXEC SQL DESCRIBE SELECT LIST FOR S1 USING DESCRIPTOR
sqlda;
if( sqlda->sqld > sqlda->sqln ){
actual_size = sqlda->sqld;
free_sqlda( sqlda );
sqlda = alloc_sqlda( actual_size );
EXEC SQL DESCRIBE SELECT LIST FOR S1
USING DESCRIPTOR sqlda;
}
fill_sqlda( sqlda );
EXEC SQL DECLARE C1 CURSOR FOR S1;
EXEC SQL OPEN C1;
EXEC SQL WHENEVER NOTFOUND {break};
for( ;; ){
EXEC SQL FETCH C1 USING DESCRIPTOR sqlda;
/* do something with data */
}
EXEC SQL CLOSE C1;
EXEC SQL DROP STATEMENT S1;
43
The SQL descriptor area (SQLDA)
#include "sqlca.h"
#define SQL_MAX_NAME_LEN 30
44
Chapter 2 The Embedded SQL Interface
struct sqlda{
unsigned char sqldaid[8]; /* eye catcher "SQLDA"*/
a_sql_int32 sqldabc; /* length of sqlda structure*/
short int sqln; /* descriptor size in number of entries */
short int sqld; /* number of variables found by DESCRIBE*/
struct sqlvar sqlvar[1]; /* array of variable descriptors */
};
#define SCALE(sqllen) ((sqllen)/256)
#define PRECISION(sqllen) ((sqllen)&0xff)
#define SET_PRECISION_SCALE(sqllen,precision,scale) \
sqllen = (scale)*256 + (precision)
#define DECIMALSTORAGE(sqllen) (PRECISION(sqllen)/2 + 1)
#endif
Field Description
sqldaid An 8-byte character field that contains the string SQLDA as an
identification of the SQLDA structure. This field helps in
debugging, when you are looking at memory contents.
sqldabc A long integer containing the length of the SQLDA structure.
sqln The number of variable descriptors in the sqlvar array.
sqld The number of variable descriptors which are valid (contain
information describing a host variable). This field is set by the
DESCRIBE statement, and sometimes by the programmer when
supplying data to the database server.
sqlvar An array of descriptors of type struct sqlvar, each describing a
host variable.
45
The SQL descriptor area (SQLDA)
46
Chapter 2 The Embedded SQL Interface
47
The SQL descriptor area (SQLDA)
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 server will perform type conversions
between any two types. The memory pointed to by the sqldata field must
correspond to the sqltype and sqllen fields.
$ For information on Embedded SQL data types, see "Embedded SQL
data types" on page 17.
48
Chapter 2 The Embedded SQL Interface
Supplying a value The following table indicates how you specify lengths of values when you
supply data to the database server in the SQLDA.
Only the data types shown in the table are allowed in this case. The
DT_DATE, DT_TIME and DT_TIMESTAMP types are treated the same as
DT_STRING when supplying information to the database; the value must be
a NULL-terminated character string in an appropriate date format.
49
The SQL descriptor area (SQLDA)
Retrieving a value The following table indicates the values of the length field when you retrieve
data from the database using a SQLDA. The sqllen field is never modified
when you retrieve data.
Only the interface data types shown in the table are allowed in this case. The
DT_DATE, DT_TIME and DT_TIMESTAMP data types are treated the
same as DT_STRING when you retrieve information from the database. The
value is formatted as a character string in the current date format.
50
Chapter 2 The Embedded SQL Interface
51
Using stored 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 data
definition statement, such as CREATE TABLE. 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 prepare and execute a CALL statement. The example
illustrates the use of host variables. Both the USING and INTO clauses are
used on the EXECUTE statement.
EXEC SQL BEGIN DECLARE SECTION;
double hv_expense;
double hv_balance;
EXEC SQL END DECLARE SECTION;
UPDATE account
SET balance = balance + expense
WHERE name = ’pettycash expense’;
52
Chapter 2 The Embedded SQL Interface
53
Using stored procedures in Embedded SQL
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 that there is another cursor. The example illustrates a two-select
procedure:
EXEC SQL CREATE PROCEDURE people()
RESULT( name char(50) )
BEGIN
Dynamic cursors These examples have used static cursors. Full dynamic cursors can also be
for CALL used for the CALL statement
statements
$ For a description of dynamic cursors, see "Dynamic SELECT
statement" on page 42.
The DESCRIBE statement works fully for procedure calls. A DESCRIBE
OUTPUT produces a SQLDA that has a description for each of the result set
columns.
If the procedure does not have a result set, the SQLDA has a description for
each INOUT or OUT parameter for the procedure. A DESCRIBE INPUT
statement will produce a SQLDA having a description for each IN or INOUT
parameter for the procedure.
DESCRIBE ALL DESCRIBE ALL describes IN, INOUT, OUT and RESULT set parameters.
DESCRIBE ALL uses the indicator variables in the SQLDA to provide
additional information.
54
Chapter 2 The Embedded SQL Interface
55
Library functions
Library functions
The SQL preprocessor generates calls to functions in the interface library or
DLL. In addition to the calls generated by the SQL preprocessor, several
routines 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.
This section contains a detailed description of these various functions by
category.
DLL entry points The DLL entry points are the same except that the prototypes have a
modifier appropriate for DLLs.
You can declare the entry points in a portable manner using _esqlentry_,
which is defined in sqlca.h. It resolves to the following values:
♦ Windows 95/98, Windows NT, Windows CE: __stdcall
All of the pointers that are 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 _esqlentry_ db_init( struct sqlca far *sqlca );
db_init function
Prototype unsigned short _esqlentry_ db_init( struct sqlca *sqlca );
Description This function initializes the database interface library. This function must be
called before any other library call is made, and before any Embedded SQL
command is executed. The resources the interface library requires for your
program are allocated and initialized on this call.
56
Chapter 2 The Embedded SQL Interface
Use db_fini to free the resources at the end of your program. If there are any
errors during processing, they are returned in the SQLCA and 0 is returned.
If there are no errors, a non-zero value is returned and you can begin using
Embedded SQL commands and functions.
In most cases, this function should be called only once (passing the address
of the global sqlca variable defined in the sqlca.h header file). If you are
writing a DLL or an application that has multiple threads using Embedded
SQL, call db_init once for each SQLCA that is being used (see "SQLCA
management for multi-threaded or reentrant code" on page 29).
Caution
Failure to call db_fini for each db_init on NetWare can cause the
database server to fail, and the NetWare file server to fail.
db_fini function
Prototype unsigned short _esqlentry_ db_fini( struct sqlca *sqlca );
This function frees resources used by the database interface or DLL. You
must not make any other library calls or execute any Embedded SQL
commands after db_fini is called. If there are any errors during processing,
they are returned in the SQLCA and 0 is returned. If there are no errors, a
non-zero value is returned.
You need to call db_fini once for each SQLCA being used.
Caution
Failure to call db_fini for each db_init on NetWare can cause the
database server to fail, and the NetWare file server to fail.
57
Library functions
db_string_connect function
Prototype unsigned _esqlentry_ db_string_connect( struct sqlca * sqlca, char * parms );
Description Provides extra functionality beyond the Embedded SQL CONNECT
command. This function carries out a connection using the algorithm
described in "Troubleshooting connections" on page 63 of the book ASA
User’s Guide.
The return value is true (non-zero) if a connection was successfully
established and false (zero) otherwise. Error information for starting the
server, starting the database, or connecting is returned in the SQLCA.
db_string_disconnect function
Prototype unsigned _esqlentry_ db_string_disconnect( struct sqlca * sqlca, char * parms
);
Description This function disconnects the connection identified by the ConnectionName
parameter. All other parameters are ignored.
If no ConnectionName parameter is specified in the string, the unnamed
connection is disconnected. This is equivalent to the Embedded SQL
DISCONNECT command. The boolean return value is true if a connection
was successfully ended. Error information is returned in the SQLCA.
This function shuts down the database if it was started with the
AutoStop=yes parameter and there are no other connections to the database.
It also stops the server if it was started with the AutoStop=yes parameter and
there are no other databases running.
58
Chapter 2 The Embedded SQL Interface
db_string_ping_server function
Prototype short _esqlentry_ db_string_ping_server(
SQLCA _fd_ * sqlca,
char _fd_ * connect_string,
unsigned int connect_to_db );
Description The connect_string is a normal connect string that may or may not contain
server and database information.
If connect_to_db is non-zero (true), then the function attempts to connect to a
database on a server. It returns a non-zero (true) value only if the connect
string is sufficient to connect to a the named database on the named server.
If connect_to_db is zero, then the function only attempts to locate a server. It
returns a non-zero value only if the connect string is sufficient to locate a
server. It makes no attempt to connect to the database.
db_start_engine function
Prototype unsigned _esqlentry_ db_start_engine( struct sqlca * sqlca,
char * parms );
Description Start the database server if it is not running. The steps carried out by this
function are those listed in "Starting a personal server" on page 69 of the
book ASA User’s Guide.
The return value is true if a database server was either found or successfully
started. Error information is returned in the SQLCA.
The following call to db_start_engine starts the database server and names
it asademo, but does not load the database, despite the DBF connection
parameter:
db_start_engine( &sqlca, "DBF=c:\\asa6\\asademo.db;
Start=dbeng7" );
If you wish to start a database as well as the server, include the database file
in the START connection parameter:
db_start_engine( &sqlca,"ENG=eng_name;START=dbeng7
c:\\asa6\\asademo.db" );
This call starts the server, names it eng_name, and starts the asademo
database on that server.
The db_start_engine function attempts to connect to a server before starting
one, to avoid attempting to start a server that is already running.
59
Library functions
If FORCESTART was not used, and without an ENG parameter, the second
command would have attempted to connect to server_1. The
db_start_engine function does not pick up the server name from the -n
switch of the START parameter.
db_start_database function
Prototype unsigned _esqlentry_ db_start_database( struct sqlca * sqlca, char * parms );
Description Start a database on an existing server if the database is not already running.
The steps carried out to start a database are described in "Starting a personal
server" on page 69 of the book ASA User’s Guide
The return value is true if the database was already running or successfully
started. Error information is returned in the SQLCA.
If a user ID and password are supplied in the parameters, they are ignored.
$ The permission required to start and stop a database is set on the server
command line. For information, see "The database server" on page 14 of the
book ASA Reference.
db_stop_database function
Prototype unsigned int _esqlentry_ db_stop_database( struct sqlca * sqlca,
char * parms );
Description Stop the database identified by DatabaseName on the server identified by
EngineName. If EngineName is not specified, the default server is used.
By default, this function does not stop a database that has existing
connections. If Unconditional is yes, the database is stopped regardless of
existing connections.
A return value of TRUE indicates that there were no errors.
$ The permission required to start and stop a database is set on the server
command line. For information, see "The database server" on page 14 of the
book ASA Reference.
60
Chapter 2 The Embedded SQL Interface
db_stop_engine function
Prototype unsigned int _esqlentry_ db_stop_engine( struct sqlca * sqlca,
char * parms );
Description Terminates execution of the database server. The steps carried out by this
function are:
♦ Look for a local database server that has a name that matches the
EngineName parameter. If no EngineName is specified, look for the
default local database server.
♦ If no matching server is found, this function fails.
♦ Send a request to the server to tell it to checkpoint and shut down all
databases.
♦ Unload the database server.
By default, this function will not stop a database server that has existing
connections. If Unconditional is yes, the database server is stopped
regardless of existing connections.
A C program can use this function instead of spawning DBSTOP. A return
value of TRUE indicates that there were no errors.
The use of db_stop_ending is subject to the permissions set on the -gk
database server command-line option. For more information, see "–gk
command-line option" on page 27 of the book ASA Reference.
db_find_engine function
Prototype unsigned short _esqlentry_ db_find_engine( struct sqlca *sqlca, char *name );
Description Returns an unsigned short value, which indicates status information about the
database server whose name is name. If no server can be found with the
specified name, the return value is 0. A non-zero value indicates that the
server is currently running.
Each bit in the return value conveys some information. Constants that
represent the bits for the various pieces of information are defined in the
sqldef.h header file. If a null pointer is specified for name, information is
returned about the default database environment.
61
Library functions
$ For a detailed description of the SQLDA, see "The SQL descriptor area
(SQLDA)" on page 44.
alloc_sqlda_noind function
Prototype struct sqlda *alloc_sqlda_noind( unsigned numvar );
Description Allocates a SQLDA with descriptors for numvar variables. The sqln field of
the SQLDA is initialized to numvar. Space is not allocated for indicator
variables; the indicator pointers are set to the null pointer. A null pointer is
returned if memory cannot be allocated.
alloc_sqlda function
Prototype struct sqlda *alloc_sqlda( unsigned numvar );
Description Allocates a SQLDA with descriptors for numvar variables. The sqln field of
the SQLDA is initialized to numvar. Space is allocated for the indicator
variables, the indicator pointers are set to point to this space, and the
indicator value is initialized to zero. A null pointer is returned if memory
cannot be allocated. It is recommended that you use this function instead of
alloc_sqlda_noind function.
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
Prototype unsigned long sqlda_string_length( struct sqlda *sqlda, int varno );
Description Returns the length of the C string (type DT_STRING) that would be required
to hold the variable sqlda->sqlvar[varno] (no matter what its type is).
sqlda_storage function
Prototype unsigned long _esqlentry_ 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].
62
Chapter 2 The Embedded SQL Interface
fill_s_sqlda function
Prototype struct sqlda *fill_s_sqlda( struct sqlda *sqlda, unsigned int maxlen );
Description The same as fill_sqlda, except that it changes all the data types in sqlda to
type DT_STRING.. Enough space is allocated to hold the string
representation of the type originally specified by the SQLDA, up to a
maximum of maxlen bytes. The length fields in the SQLDA (sqllen) are
modified appropriately. Returns sqlda if successful and returns the null
pointer if there is not enough memory available.
free_filled_sqlda function
Prototype void _esqlentry_ free_filled_sqlda( struct sqlda *sqlda );
Description Free the memory allocated to each sqldata pointer, and the space allocated
for the SQLDA itself. Any null pointer is not freed.
Calling this function causes free_sqlda to be called automatically, and so
any descriptors allocated by alloc_sqlda are freed.
free_sqlda_noind function
Prototype void _esqlentry_ free_sqlda_noind( struct sqlda *sqlda );
Description Free space allocated to this sqlda. Do not free the memory referenced by
each sqldata pointer. The indicator variable pointers are ignored.
free_sqlda function
Prototype void _esqlentry_ free_sqlda( struct sqlda *sqlda );
Description Free space allocated to this sqlda, and free the indicator variable space, as
allocated in fill_sqlda. Do not free the memory referenced by each sqldata
pointer.
Backup functions
The db_backup function provides support for online backup. The Adaptive
Server 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 Adaptive Server Anywhere backup utility.
$ You can also access the backup utility directly using the Database
Tools DBBackup function. For more information on this function, see
"DBBackup function" on page 93.
63
Library functions
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 into fixed size pages, and the size of these pages is
specified when the database is created.
Backup works by opening a file, and then making a copy of each page in the
file. Backup performs a checkpoint on startup, and the database files are
backed up as of this checkpoint. Any changes that are made while the backup
is running are recorded in the transaction log, and are backed up with the
transaction log. This is why the transaction log is always backed up 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
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 depends on the value of the op parameter:
♦ DB_BACKUP_START Must be called before a backup can start. Only
one backup can be running at one time against any given database
server. Database checkpoints are disabled until the backup is complete
(db_backup is called with an op value of DB_BACKUP_END). If the
backup cannot start, the SQLCODE is
SQLE_BACKUP_NOT_STARTED. Otherwise, the SQLCOUNT field
of the sqlca is set to the size of each database page. (Backups are
processed one page at a time.)
The file_num, page_num and sqlda parameters are ignored.
♦ DB_BACKUP_OPEN_FILE Open the database file specified by
file_num, which allows pages of the specified file to be backed up using
DB_BACKUP_READ_PAGE. Valid file numbers are 0 through
DB_BACKUP_MAX_FILE for the 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 is SQLE_NOTFOUND.
Otherwise, SQLCOUNT contains the number of pages in the file,
SQLIOESTIMATE contains a 32-bit value (POSIX time_t) which
identifies the time that the database file was created, and the operating
system file name is in the sqlerrmc field of the SQLCA.
64
Chapter 2 The Embedded SQL Interface
65
Library functions
You should not call db_backup again after this, except to close files and
finish the backup. If you do, you get a second copy of your backed up
log file and you receive SQLE_NOTFOUND.
♦ DB_BACKUP_CLOSE_FILE Must be called when processing of one
file is complete to close the database file specified by file_num.
The page_num and sqlda parameters are ignored.
♦ DB_BACKUP_END Must be called at the end of the backup. No other
backup can start until this backup has ended. Checkpoints are enabled
again.
The file_num, page_num and sqlda parameters are ignored.
The dbbackup program uses the following algorithm. Note that this is not C
code, and does not include error checking.
db_backup( ... DB_BACKUP_START ... )
allocate page buffer based on page size in SQLCODE
sqlda = alloc_sqlda( 1 )
sqlda->sqld = 1;
sqlda->sqlvar[0].sqltype = DT_BINARY
sqlda->sqlvar[0].sqldata = allocated buffer
for file_num = 0 to DB_BACKUP_MAX_FILE
db_backup( ... DB_BACKUP_OPEN_FILE, file_num ... )
if SQLCODE == SQLE_NO_ERROR
/* The file exists */
num_pages = SQLCOUNT
file_time = SQLE_IO_ESTIMATE
open backup file with name from sqlca.sqlerrmc
for page_num = 0 to num_pages - 1
db_backup( ... DB_BACKUP_READ_PAGE,
file_num, page_num, sqlda )
write page buffer out to backup file
next page_num
close backup file
db_backup( ... DB_BACKUP_CLOSE_FILE, file_num ... )
end if
next file_num
backup up file DB_BACKUP_WRITE_FILE as above
backup up file DB_BACKUP_TRANS_LOG_FILE as above
free page buffer
db_backup( ... DB_BACKUP_END ... )
db_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).
66
Chapter 2 The Embedded SQL Interface
Description The db_delete_file function requests the database server to delete filename.
This can be used after backing up and renaming the transaction log (see
DB_BACKUP_READ_RENAME_LOG above) to delete the old transaction
log. You must be connected to a user ID with DBA authority.
db_cancel_request function
Prototype int db_cancel_request( struct sqlca *sqlca );
Description Cancels the currently active database server request. This function will check
to make sure a database server request is active before sending the cancel
request. If the function returns 1, then the cancel request was sent; if it
returns 0, then no request was sent.
A non-zero return value does not mean that the request was canceled. There
are a few critical timing cases where the cancel request and the response
from the database or server "cross". In these cases, the cancel simply has no
effect, even though the function still returns TRUE.
67
Library functions
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. 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_register_a_callback function
Prototype void SQL_CALLBACK db_register_a_callback( struct sqlca *sqlca,
a_db_callback_index index,
(SQL_CALLBACK_PARM)callback );
Description This function registers callback functions.
You should call MakeProcInstance with your function address and pass that
to the db_register_a_callback function.
If you do not register any callback functions, the default action is to do
nothing. Your application blocks, waiting for the database response, and
Windows changes the cursor to an hourglass.
To remove a callback, pass a null pointer as the callback function.
The following values are allowed for the index parameter:
♦ DB_CALLBACK_START The prototype is as follows:
void SQL_CALLBACK db_start_request( struct sqlca
*sqlca );
This function is called just before a database request is sent to the server.
♦ DB_CALLBACK_FINISH The prototype is as follows:
void SQL_CALLBACK db_finish_request( struct sqlca
*sqlca );
68
Chapter 2 The Embedded SQL Interface
This function is called after the response to a database request has been
received by the interface DLL.
DB_CALLBACK_START and DB_CALLBACK_FINISH are used only on
Windows 95/98, Windows NT, and Windows CE.
♦ DB_CALLBACK_WAIT The prototype is as follows:
void SQL_CALLBACK db_wait_request( struct sqlca
*sqlca );
This function is called repeatedly by the interface DLL while the
database server or client library is busy processing your database
request.
The following is a sample DB_CALLBACK_WAIT callback function:
void SQL_CALLBACK db_wait_request( struct sqlca
*sqlca )
{ MSG msg
if( GetMessage( &msg, NULL, 0, 0 ) ) {
( !db_process_a_message( sqlca, &msg ) ) {
if( !TranslateAccelerator( hWnd, hAccel, &msg
) ) {
TranslateMessage( &msg )
DispatchMessage( &msg )
}
}
}
}
You would register this callback as follows:
db_register_a_callback( &sqlca,
DBCALLBACK_MESSAGE,
(SQL_CALLBACK_PARM)&db_wait_request );
♦ DB_CALLBACK_MESSAGE This is used to enable the application to
handle messages received from the server during the processing of a
request.
The callback prototype is as follows:
void SQL_CALLBACK message_callback( SQLCA* sqlca,
unsigned short msg_type,
an_sql_code code,
unsigned length,
char* msg )
69
Library functions
The msg_type parameter states how important the message is, and you
may wish to handle different message types in different ways. The
available message types are MESSAGE_TYPE_INFO,
MESSAGE_TYPE_WARNING, MESSAGE_TYPE_ACTION and
MESSAGE_TYPE_STATUS. These constants are defined in sqldef.h.
The code field is an identifier. The length field tells you how long the
message is. The message is not null-terminated.
For example, the Interactive SQL callback displays STATUS and INFO
message in the message window, while messages of type ACTION and
WARNING go to a dialog box. If an application does not register this
callback, there is a default callback, which causes all messages to be
written to the server logfile (if debugging is on and a logfile is
specified). In addition, messages of type
MESSAGE_TYPE_WARNING and MESSAGE_TYPE_ACTION are
more prominently displayed, in an operating system-dependent manner.
Other functions
The following functions are miscellaneous functions.
sql_needs_quotes function
Prototype unsigned int sql_needs_quotes( struct sqlca *sqlca, char *str );
Description Returns a Boolean value that indicates whether the string requires double
quotes around it when it is used as a SQL identifier. This function formulates
a request to the database server to determine if quotes are needed. Relevant
information is stored in the sqlcode field.
There are three cases of return value/code combinations:
♦ return = FALSE, sqlcode = 0 In this case, the string definitely does
not need quotes
♦ return = TRUE In this case, sqlcode is always SQLE_WARNING, and
the string definitely does need quotes
♦ If sqlcode is something other than
return = FALSE
SQLE_WARNING, the test is inconclusive
sqlerror_message function
Prototype char *sqlerror_message( struct sqlca *sqlca, char * buffer, int max );
70
Chapter 2 The Embedded SQL Interface
Description Return a pointer to a string that contains an error message. The error message
contains text for the error code in the SQLCA. If no error was indicated, a
null pointer is returned. The error message is placed in the buffer supplied,
truncated to length max if necessary.
71
Embedded SQL commands
EXEC SQL
ALL Embedded SQL statements must be preceded with EXEC SQL and
end with a semicolon.
72
Chapter 2 The Embedded SQL Interface
73
Database examples
Database examples
Two Embedded SQL examples are included with the Adaptive Server
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 Adaptive Server Anywhere which
demonstrate features available for particular platforms.
File locations Source code for the examples is installed as part of the Adaptive Server
Anywhere installation. They are placed in the cxmp subdirectory of your
Adaptive Server Anywhere installation directory.
74
Chapter 2 The Embedded SQL Interface
Windows and The Windows versions of the example programs are real Windows programs.
Windows NT However, to keep the user interface code relatively simple, some
examples simplifications have been made. In particular, these applications do not
repaint their Windows on WM_PAINT messages except to reprint the
prompt.
To run these programs, execute them using the curwin executable name.
75
Database examples
76
Chapter 2 The Embedded SQL Interface
A cursor is then declared and opened for this statement. The rest of the
routines for moving and closing the cursor remain the same.
77
Database examples
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.
78
Chapter 2 The Embedded SQL Interface
Switch Description
–c "keyword=value;..." Supply reference database connection parameters
[UltraLite]
–d Favor data size
–e level Flag non-conforming SQL syntax as an error
–f Put the far keyword on generated static data
–h line-width Limit the maximum line length of output
–k Include user declaration of SQLCODE
–n Line numbers
–o operating-sys Target operating system: WIN32, WINNT, NETWARE,
or UNIX
–p project UltraLite project name
–q Quiet mode—do not print banner
–r Generate reentrant code
–s string-len Maximum string length for the compiler
–w level Flag non-conforming SQL syntax as a warning
–x Change multibyte SQL strings to escape sequences.
–z sequence Specify collation sequence
79
The SQL preprocessor
Favor data size (–d) Generate code that reduces data space size. Data
structures will be reused and initialized at execution time before use. This
increases code size.
Flag SQL/92 errors (–e) This option flags any Embedded SQL that is not
part of a specified set of SQL/92 as an error.
Add far keyword (–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.)
Limit maximum output line length (–h) Limits the maximum length of
lines output by sqlpp to num. The continuation character is a backslash (\),
and the minimum value of num is ten.
Target operating system (–o) Specify the target operating system. Note
that this option must match the operating system where you will run the
program. A reference to a special symbol will be generated in your program.
This symbol is defined in the interface library. If you use the wrong
operating system specification or the wrong library, an error will be detected
by the linker. The supported operating systems are:
80
Chapter 2 The Embedded SQL Interface
Set maximum string size (–s) 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.
Flag SQL/92 warnings (–w) This option flags any Embedded SQL that is
not part of a specified set of SQL/92 as a warning.
81
The SQL preprocessor
82
C H A P T E R 3
About this chapter This chapter describes how to use the database tools library that is provided
with Adaptive Server Anywhere to add database management features to C
or C++ applications.
Contents
Topic Page
Introduction to the database tools interface 84
Using the database tools interface 85
DBTools functions 93
DBTools structures 102
DBTools enumeration types 125
83
Introduction to the database tools interface
84
Chapter 3 The Database Tools Interface
85
Using the database tools interface
// initialize DBTools
ret = DBToolsInit( &info );
if( ret != EXIT_OKAY ) {
// DLL initialization failed
…
}
// call some DBTools routines . . .
…
// cleanup the DBTools dll
DBToolsFini( &info );
86
Chapter 3 The Database Tools Interface
Code Explanation
0 Success
1 General failure
2 Invalid file format
3 File not found, unable to open
4 Out of memory
5 Terminated by the user
6 Failed communications
7 Missing a required database name
8 Client/server protocol mismatch
9 Unable to connect to the database server
10 Database server not running
11 Database server not found
254 Reached stop time
255 Invalid parameters on the command line
87
Using the database tools interface
Assigning a In operating systems other than Windows 3.x, you can directly assign a
callback function to callback routine to the structure. The following statement is an example
a structure using a backup structure:
backup_info.errorrtn = (MSG_CALLBACK) MyFunction
MSG_CALLBACK is defined in the dllapi.h header file supplied with
Adaptive Server Anywhere. Tools routines can call back to the Calling
application with messages that should be displayed in the appropriate user
interface, whether that be a windowing environment, standard output on a
character-based systems, or other user interface.
If you are developing for Windows 3.x, you must use the MakeProcInstance
Windows API thunking function when assigning values to the elements. A
thunking function changes 16-bit values to equivalent 32-bit values. The
following statement is an example using a backup structure:
backup_info.errorrtn =
(MSG_CALLBACK)MakeProcInstance(
(FARPROC)MyFunction, hInst );
After you have finished with the DLL, you must free Callback thunk using
the FreeProcInstance Windows API function:
FreeProcInstance( (FARPROC) backup_info.errorrtn );
If no function is assigned to the structure member, the message is ignored.
Confirmation The following example confirmation routine asks the user to answer YES or
callback function NO to a prompt, and returns the user’s selection:
example extern short _callback ConfirmRtn(
char far * question )
{
int ret;
if( question != NULL ) {
ret = MessageBox( HwndParent, question,
"Confirm", MB_ICONEXCLAMTION|MB_YESNO );
}
return( 0 );
}
Error callback The following is an example of an error message handling routine, which
function example displays the error message in a message box.
extern short _callback ErrorRtn(
char far * errorstr )
{
if( errorstr != NULL ) {
ret = MessageBox( HwndParent, errorstr,
"Backup Error", MB_ICONSTOP|MB_OK );
88
Chapter 3 The Database Tools Interface
}
return( 0 );
}
Status callback A status callback routine is called when the tools needs to display the status
function example of an operation (like the percentage done unloading a table). Again, a
common implementation would just output the message to the screen:
extern short _callback StatusRtn(
char far * statusstr )
{
if( statusstr == NULL ) {
return FALSE;
}
OutputMessageToWindow( statustr );
return TRUE;
}
Compatibility The version number allows your application to continue working against
newer versions of the DBTools library. The DBTools functions use the
version number supplied by your application to allow the application to
work, even if new members have been added to the DBTools structure.
89
Using the database tools interface
Applications will not work against older versions of the DBTools library.
A DBTools example
The following program illustrates the use of the DBTools library in the
context of a backup program:
# define WINNT
#include <stdio.h>
#include "windows.h"
#include "string.h"
#include "dbtools.h"
90
Chapter 3 The Database Tools Interface
91
Using the database tools interface
92
Chapter 3 The Database Tools Interface
DBTools functions
This section describes the functions available in the DBTools library. The
functions are listed alphabetically.
DBBackup function
Function Database backup function. This function is used by the DBBACKUP
command-line utility.
Prototype short DBBackup ( const backup_db * );
Parameters Parameter Description
backup_db Pointer to "a_backup_db structure" on page 102
Return value A return code, as listed in "Software component return codes" on page 87.
Usage The DBBackup function manages all database backup tasks. For descriptions
of these tasks, see "The Backup utility" on page 74 of the book ASA
Reference.
See Also "a_backup_db structure" on page 102
DBChangeLogName function
Function Changes the name of the transaction log file. This function is used by the
dblog command-line utility.
Prototype short DBChangeLogName ( const change_log * );
Parameters Parameter Description
change_log Pointer to "a_change_log structure" on page 104
Return value A return code, as listed in "Software component return codes" on page 87.
Usage The -t option of the dblog command line utility changes the name of the
transaction log. DBChangeLogName provides a programmatic interface to
this function.
For descriptions of the dblog utility, see "The Transaction Log utility" on
page 120 of the book ASA Reference.
See Also "a_change_log structure" on page 104
93
DBTools functions
DBChangeWriteFile function
Function Changes a write file to refer to another database file. This function is used by
the dbwrite command-line utility when the -d option is applied.
Prototype short DBChangeWriteFile ( const writefile * );
Parameters Parameter Description
writefile Pointer to "a_writefile structure" on page 123
Return value A return code, as listed in "Software component return codes" on page 87.
Usage For information about the Write File utility and its features, see "The Write
File utility" on page 139 of the book ASA Reference.
See Also "DBCreateWriteFile function" on page 95
"DBStatusWriteFile function" on page 98
"a_writefile structure" on page 123
DBCollate function
Function Extracts a collation sequence from a database.
Prototype short DBCollate ( const db_collation * );
Parameters Parameter Description
db_collation Pointer to "a_db_collation structure" on page 109
Return value A return code, as listed in "Software component return codes" on page 87.
Usage For information about the collation utility and its features, see "The Collation
utility" on page 78 of the book ASA Reference
See Also "a_db_collation structure" on page 109
DBCompress function
Function Compresses a database file. This function is used by the dbshrink command-
line utility.
Prototype short DBCompress ( const compress_db * );
Parameters Parameter Description
compress_db Pointer to "a_compress_db structure" on page 105
94
Chapter 3 The Database Tools Interface
DBCreate function
Function Creates a database. This function is used by the dbinit command-line utility.
Prototype short DBCreate ( const create_db * );
Parameters Parameter Description
create_db Pointer to "a_create_db structure" on page 107
Return value A return code, as listed in "Software component return codes" on page 87.
Usage For information about the initialization utility, see "The Initialization utility"
on page 92 of the book ASA Reference.
See Also "a_create_db structure" on page 107
DBCreateWriteFile function
Function Creates a write file. This function is used by the dbwrite command-line utility
when the -c option is applied.
Prototype short DBCreateWriteFile ( const writefile * );
Parameters Parameter Description
writefile Pointer to "a_writefile structure" on page 123
Return value A return code, as listed in "Software component return codes" on page 87.
Usage For information about the Write File utility and its features, see "The Write
File utility" on page 139 of the book ASA Reference.
See Also "DBChangeWriteFile function" on page 94
"DBStatusWriteFile function" on page 98
"a_writefile structure" on page 123
95
DBTools functions
DBErase function
Function Erases a database file and/or transaction log file. This function is used by the
dberase command-line utility.
Prototype short DBErase ( const erase_db * );
Parameters Parameter Description
erase_db Pointer to "an_erase_db structure" on page 112
Return value A return code, as listed in "Software component return codes" on page 87.
Usage For information about the Erase utility and its features, see "The Erase
utility" on page 88 of the book ASA Reference.
See Also "an_erase_db structure" on page 112
DBExpand function
Function Uncompresses a database file. This function is used by the dbexpand
command-line utility.
Prototype short DBExpand ( const expand_db * );
Parameters Parameter Description
&an_expand_db Pointer to "an_expand_db structure" on page 113
Return value A return code, as listed in "Software component return codes" on page 87.
Usage For information about the Uncompression utility and its features, see "The
Uncompression utility" on page 124 of the book ASA Reference.
See Also "an_expand_db structure" on page 113
DBInfo function
Function Returns information about a database file. This function is used by the dbinfo
command-line utility.
Prototype short DBInfo ( const db_info * );
Parameters Parameter Description
db_info Pointer to "a_db_info structure" on page 110
Return value A return code, as listed in "Software component return codes" on page 87.
96
Chapter 3 The Database Tools Interface
For information about the Information utility and its features, see "The
Usage
Information utility" on page 90 of the book ASA Reference.
See Also "DBInfoDump function" on page 97
"DBInfoFree function" on page 97
"a_db_info structure" on page 110
DBInfoDump function
Function Returns information about a database file. This function is used by the dbinfo
command-line utility when the -u option is used.
Prototype short DBInfoDump ( const db_info * );
Parameters Parameter Description
db_info Pointer to "a_db_info structure" on page 110
Return value A return code, as listed in "Software component return codes" on page 87.
Usage For information about the Information utility and its features, see "The
Information utility" on page 90 of the book ASA Reference.
See Also "DBInfo function" on page 96
"DBInfoFree function" on page 97
"a_db_info structure" on page 110
DBInfoFree function
Function Called to free resources after the DBInfoDump function is called.
Prototype short DBInfoFree ( const db_info * );
Parameters Parameter Description
db_info Pointer to "a_db_info structure" on page 110
Return value A return code, as listed in "Software component return codes" on page 87.
Usage For information about the Information utility and its features, see "The
Information utility" on page 90 of the book ASA Reference.
See Also "DBInfo function" on page 96
"DBInfoDump function" on page 97
"a_db_info structure" on page 110
97
DBTools functions
DBStatusWriteFile function
Function Gets the status of a write file. This function is used by the dbwrite command-
line utility when the -s option is applied.
Prototype short DBStatusWriteFile ( const writefile * );
Parameters Parameter Description
writefile Pointer to "a_writefile structure" on page 123
Return value A return code, as listed in "Software component return codes" on page 87.
Usage For information about the Write File utility and its features, see "The Write
File utility" on page 139 of the book ASA Reference.
See Also "DBChangeWriteFile function" on page 94
"DBCreateWriteFile function" on page 95
"a_writefile structure" on page 123
DBToolsFini function
Function Decrements the counter and frees resources when an application is finished
with the DBTools library.
Prototype short DBToolsFini ( const dbtools_info * );
Parameters Parameter Description
dbtools_info Pointer to "a_dbtools_info structure" on page 111
Return value A return code, as listed in "Software component return codes" on page 87.
Usage The DBToolsFini function must be called at the end of any application that
uses the DBTools interface. Failure to do so can lead to lost memory
resources.
See Also "DBToolsInit function" on page 98
"a_dbtools_info structure" on page 111
DBToolsInit function
Function Prepares the DBTools library for use.
Prototype short DBToolsInit t( const dbtools_info * );
98
Chapter 3 The Database Tools Interface
Return value A return code, as listed in "Software component return codes" on page 87.
Usage The primary purpose of the DBToolsInit function is to load the Adaptive
Server Anywhere language DLL. The language DLL contains localized
versions of error messages and prompts that DBTools uses internally.
The DBToolsInit function must be called at the start of any application that
uses the DBTools interface, before any other DBTools functions.
Example ♦ The following code sample illustrates how to initialize and clean up
DBTools:
a_dbtools_info info;
short ret;
// initialize DBTools
ret = DBToolsInit( &info );
if( ret != EXIT_OKAY ) {
// DLL initialization failed
…
}
// call some DBTools routines . . .
…
// cleanup the DBTools dll
DBToolsFini( &info );
DBToolsVersion function
Function Returns the version number of the DBTools library.
Prototype short DBToolsVersion ( void );
Return value A short integer indicating the version number of the DBTools library.
Usage Use the DBToolsVersion function to check that the DBTools library is not
older than one against which your application is developed. While
applications can run against newer versions of DBTools, they cannot run
against older versions.
99
DBTools functions
DBTranslateLog function
Function Translates a transaction log file to SQL. This function is used by the dbtran
command-line utility.
Prototype short DBTranslateLog ( const translate_log * );
Parameters Parameter Description
translate_log Pointer to "a_translate_log structure" on page 116
Return value A return code, as listed in "Software component return codes" on page 87.
Usage For information about the log translation utility, see "The Log Translation
utility" on page 109 of the book ASA Reference.
See Also "a_translate_log structure" on page 116
DBTruncateLog function
Function Truncates a transaction log file. This function is used by the dbbackup
command-line utility.
Prototype short DBTruncateLog ( const truncate_log * );
Parameters Parameter Description
truncate_log Pointer to "a_truncate_log structure" on page 117
Return value A return code, as listed in "Software component return codes" on page 87.
Usage For information about the backup utility, see "The Backup utility" on
page 74 of the book ASA Reference
See Also "a_truncate_log structure" on page 117
DBUnload function
Function Unloads a database. This function is used by the dbunload command-line
utility and also by the dbxtract utility for SQL Remote.
Prototype short DBUnload ( const unload_db * );
100
Chapter 3 The Database Tools Interface
Return value A return code, as listed in "Software component return codes" on page 87.
Usage For information about the Unload utility, see "The Unload utility" on
page 126 of the book ASA Reference.
See Also "an_unload_db structure" on page 118
DBUpgrade function
Function Upgrades a database file. This function is used by the dbupgrade command-
line utility.
Prototype short DBUpgrade ( const upgrade_db * );
Parameters Parameter Description
upgrade_db Pointer to "an_upgrade_db structure" on page 121
Return value A return code, as listed in "Software component return codes" on page 87.
Usage For information about the upgrade utility, see "The Upgrade utility" on
page 133 of the book ASA Reference.
See Also "an_upgrade_db structure" on page 121
DBValidate function
Function Validates all or part of a database. This function is used by the dbvalid
command-line utility.
Prototype short DBValidate ( const validate_db * );
Parameters Parameter Description
validate_db Pointer to "a_validate_db structure" on page 122
Return value A return code, as listed in "Software component return codes" on page 87.
Usage For information about the upgrade utility, see "The Validation utility" on
page 136 of the book ASA Reference.
See Also "a_validate_db structure" on page 122
101
DBTools structures
DBTools structures
This section lists the structures that are used to exchange information with
the DBTools library. The structures are listed alphabetically.
Many of the structure elements correspond to command-line switches on the
corresponding utility. For example, several structures have a member named
quiet, which can take on values of 0 or 1. This member corresponds to the
quiet operation (-q) command-line option used by many of the utilities.
a_backup_db structure
Function Holds the information needed to carry out backup tasks using the DBTools
library.
Syntax typedef struct a_backup_db {
unsigned short version;
const char * output_dir;
const char * connectparms;
const char * startline;
MSG_CALLBACK confirmrtn;
MSG_CALLBACK errorrtn;
MSG_CALLBACK msgrtn;
MSG_CALLBACK statusrtn;
char backup_database : 1;
char backup_logfile : 1;
char backup_writefile: 1;
char no_confirm : 1;
char quiet : 1;
char rename_log : 1;
char truncate_log : 1;
char rename_local_log: 1;
const char * hotlog_filename;
} a_backup_db;
102
Chapter 3 The Database Tools Interface
103
DBTools structures
a_change_log structure
Function Holds the information needed to carry out dblog tasks using the DBTools
library.
Syntax typedef struct a_change_log {
unsigned short version;
const char * dbname;
const char * logname;
MSG_CALLBACK errorrtn;
MSG_CALLBACK msgrtn;
char query_only : 1;
char quiet : 1;
char mirrorname_present : 1;
char change_mirrorname : 1;
char change_logname : 1;
char ignore_ltm_trunc: 1;
char ignore_remote_trunc : 1;
char set_generation_number : 1;
const char * mirrorname;
unsigned short generation_number;
} a_change_log;
Parameters Member Description
version DBTools version number
dbname Database file name
logname The name of the transaction log. If set to NULL, there
is no log
errorrtn Callback routine for handling an error message
msgrtn Callback routine for handling an information message
query_only If 1, just display the name of the transaction log. If 0,
permit changing of the log name
quiet Operate without printing messages (1), or print
messages (0)
mirrorname_present Set to 1. Indicates that the version of DBTools is recent
enough to support the mirrorname field
change_mirrorname If 1, permit changing of the log mirror name
change_logname If 1, permit changing of the transaction log name
104
Chapter 3 The Database Tools Interface
Member Description
ignore_ltm_trunc When using the Log Transfer Manager, performs the
same function as the dbcc settrunc( ’ltm’, ’gen_id’, n )
Replication Server function:
For information on dbcc, see your Replication Server
documentation
ignore_remote_trunc For SQL Remote. Resets the offset kept for the
purposes of the DELETE_OLD_LOGS option,
allowing transaction logs to be deleted when they are
no longer needed
set_generation_number When using the Log Transfer Manager, used after a
backup is restored to set the generation number
mirrorname The new name of the transaction log mirror file
generation_number The new generation number. Used together with
set_generation_number
a_compress_db structure
Function Holds the information needed to carry out database compression tasks using
the DBTools library.
Syntax typedef struct a_compress_db {
unsigned short version;
const char * dbname;
const char * compress_name;
MSG_CALLBACK errorrtn;
MSG_CALLBACK msgrtn;
MSG_CALLBACK statusrtn;
char display_free_pages : 1;
char quiet : 1;
char record_unchanged : 1;
a_compress_stats * stats;
MSG_CALLBACK confirmrtn;
char noconfirm : 1;
} a_compress_db;
105
DBTools structures
a_compress_stats structure
Function Holds information describing compressed database file statistics.
Syntax typedef struct a_compress_stats {
a_stats_line tables;
a_stats_line indices;
a_stats_line other;
a_stats_line free;
a_stats_line total;
long free_pages;
long unchanged;
} a_compress_stats;
106
Chapter 3 The Database Tools Interface
a_create_db structure
Function Holds the information needed to create a database using the DBTools library.
Syntax typedef struct a_create_db {
unsigned short version;
const char * dbname;
const char * logname;
const char * startline;
short page_size;
const char * default_collation;
MSG_CALLBACK errorrtn;
MSG_CALLBACK msgrtn;
short database_version;
char verbose;
char blank_pad : 2;
char respect_case : 1;
char encrypt : 1;
char debug : 1;
char dbo_avail : 1;
char mirrorname_present : 1;
char avoid_view_collisions : 1;
short collation_id;
const char * dbo_username;
const char * mirrorname;
} a_create_db;
107
DBTools structures
108
Chapter 3 The Database Tools Interface
a_db_collation structure
Function Holds the information needed to extract a collation sequence from a database
using the DBTools library.
Syntax typedef struct a_db_collation {
unsigned short version;
const char * connectparms;
const char * startline;
const char * collation_label;
const char * filename;
MSG_CALLBACK confirmrtn;
MSG_CALLBACK errorrtn;
MSG_CALLBACK msgrtn;
char include_empty : 1;
char hex_for_extended: 1;
char replace : 1;
char quiet : 1;
} a_db_collation;
Parameters Member Description
version DBTools version number.
connectparms The parameters needed to connect to the database. They take
the form of connection strings, such as the following:
"UID=DBA;PWD=SQL;DBF=c:\asa6\asademo.db"
$ For the full range of connection string options, see
"Connection parameters" on page 60 of the book ASA User’s
Guide
startline The command line used to start the database engine. The
following is an example start line:
"c:\asa6\win32\dbeng7.exe"
The default start line is used if this member is NULL.
confirmrtn Callback routine for confirming an action.
errorrtn Callback routine for handling an error message.
msgrtn Callback routine for handling an information message.
include_empty Write empty mappings for gaps in the collations sequence.
hex_for_extended Use two-digit hexadecimal numbers to represent high-value
characters.
replace Operate without confirming actions.
quiet Operate without messages.
109
DBTools structures
a_db_info structure
Function Holds the information needed to return dbinfo information using the
DBTools library.
Syntax typedef struct a_db_info {
unsigned short version;
MSG_CALLBACK errorrtn;
const char * dbname;
unsigned short dbbufsize;
char * dbnamebuffer;
unsigned short logbufsize;
char * lognamebuffer;
unsigned short wrtbufsize;
char * wrtnamebuffer;
char quiet : 1;
char mirrorname_present : 1;
a_sysinfo sysinfo;
unsigned long free_pages;
unsigned char compressed : 1;
const char * connectparms;
const char * startline;
MSG_CALLBACK msgrtn;
MSG_CALLBACK statusrtn;
unsigned char page_usage : 1;
a_table_info * totals;
unsigned long file_size;
unsigned long unused_pages;
unsigned long other_pages;
unsigned short mirrorbufsize;
char * mirrornamebuffer;
} a_db_info;
Parameters Member Description
version DBTools version number.
errortrn Callback routine for handling an error message.
dbname Database file name.
dbbufsize The length of the dbnamebuffer member.
dbnamebuffer Database file name.
logbufsize The length of the lognamebuffer member.
lognamebuffer Transaction log file name.
wrtbufsize The length of the wrtnamebuffer member.
110
Chapter 3 The Database Tools Interface
Member Description
wrtnamebuffer The write file name.
quiet Operate without confirming messages.
mirrorname_present Set to 1. Indicates that the version of DBTools is recent
enough to support the mirrorname field.
sysinfo Pointer to a_sysinfo structure.
free_pages Number of free pages.
compressed 1 if compressed, otherwise 0.
connectparms The parameters needed to connect to the database. They
take the form of connection strings, such as the following:
"UID=DBA;PWD=SQL;DBF=c:\sa50\asademo.db"
$ For the full range of connection string options, see
"Connection parameters" on page 60 of the book ASA
User’s Guide.
startline The command line used to start the database engine. The
following is an example start line:
"c:\asa6\win32\dbeng7.exe"
The default start line is used if this member is NULL.
msgrtn Callback routine for handling an information message.
statusrtn Callback routine for handling a status message.
page_usage 1 to report page usage statistics, otherwise 0.
totals Pointer to a_table_info structure.
file_size Size of database file.
unused_pages Number of unused pages.
other_pages Number of pages that are neither table nor index pages.
mirrorbufsize The length of the mirrornamebuffer member.
mirrornamebuffer The transaction log mirror name.
a_dbtools_info structure
Function Holds the information needed to start and finish working with the DBTools
library.
111
DBTools structures
an_erase_db structure
Function Holds information needed to erase a database using the DBTools library.
Syntax typedef struct an_erase_db {
unsigned short version;
const char * dbname;
MSG_CALLBACK confirmrtn;
MSG_CALLBACK errorrtn;
MSG_CALLBACK msgrtn;
char quiet : 1;
char erase : 1;
} an_erase_db;
Parameters Member Description
version DBTools version number.
dbname Database file name to erase.
confirmrtn Callback routine for confirming an action.
errorrtn Callback routine for handling an error message.
msgrtn Callback routine for handling an information message.
quiet Operate without printing messages (1), or print messages (0).
erase Erase without confirmation (1) or with confirmation (0).
112
Chapter 3 The Database Tools Interface
an_expand_db structure
Function Holds information needed for database expansion using the DBTools library.
Syntax typedef struct an_expand_db {
unsigned short version;
const char * compress_name;
const char * dbname;
MSG_CALLBACK errorrtn;
MSG_CALLBACK msgrtn;
MSG_CALLBACK statusrtn;
char quiet : 1;
MSG_CALLBACK confirmrtn;
char noconfirm : 1;
} an_expand_db;
Parameters Member Description
version DBTools version number.
compress_name Name of compressed database file
dbname Database file name
errorrtn Callback routine for handling an error message.
msgrtn Callback routine for handling an information message.
statusrtn Callback routine for handling a status message.
quiet Operate without printing messages (1), or print messages (0).
confirmrtn Callback routine for confirming an action.
noconfirm Operate with (0) or without (1) confirmation.
a_name structure
Function Holds a linked list of names. This is used by other structures requiring lists of
names.
Syntax typedef struct a_name {
struct a_name * next;
char name[1];
} a_name, * p_name;
113
DBTools structures
a_stats_line structure
Function Holds information needed for database compression and expansion using the
DBTools library.
Syntax typedef struct a_stats_line {
long pages;
long bytes;
long compressed_bytes;
} a_stats_line;
Parameters Member Description
pages Number of pages.
bytes Number of bytes for uncompressed database.
compressed_bytes Number of bytes for compressed database.
a_sysinfo structure
Function Holds information needed for dbinfo and dbunload utilities using the
DBTools library.
Syntax typedef struct a_sysinfo {
char valid_data : 1;
char blank_padding : 1;
char case_sensitivity: 1;
char encryption : 1;
char default_collation[11];
unsigned short page_size;
} a_sysinfo;
114
Chapter 3 The Database Tools Interface
a_table_info structure
Function Holds information about a table needed as part of the a_db_info structure.
Syntax typedef struct a_table_info {
struct a_table_info * next;
unsigned short table_id;
unsigned long table_pages;
unsigned long index_pages;
unsigned long table_used;
unsigned long index_used;
char * table_name;
} a_table_info;
Parameters Member Description
next Next table in the list
table_id ID number for this table
table_pages Number of table pages
index_pages Number of index pages
table_used Number of bytes used in table pages
index_used Number of bytes used in index pages
table_name Name of the table
115
DBTools structures
a_translate_log structure
Function Holds information needed for transaction log translation using the DBTools
library.
Syntax typedef struct a_translate_log {
unsigned short version;
const char * logname;
const char * sqlname;
p_name userlist;
MSG_CALLBACK confirmrtn;
MSG_CALLBACK errorrtn;
MSG_CALLBACK msgrtn;
char userlisttype;
char remove_rollback : 1;
char ansi_sql : 1;
char since_checkpoint: 1;
char omit_comments : 1;
char replace : 1;
char debug : 1;
char include_trigger_trans : 1;
char comment_trigger_trans : 1;
unsigned long since_time;
} a_translate_log;
Parameters Member Description
version DBTools version number.
logname The name of the transaction log file.
sqlname The name of the SQL command file.
userlist Pointer to a linked list of users.
confirmrtn Callback routine for confirming an action.
errorrtn Callback routine for handling an error message.
msgrtn Callback routine for handling an information
message.
userlisttype A member of the "dbtran_userlist_type enumeration"
on page 126.
remove_rollback 1 to remove changes that have been rolled back. 0
otherwise.
ansi_sql If set to 0, generate UPDATE statements with a non-
standard FIRST keyword. This is for cases where
there is no primary key or unique index on a table, in
case of duplicate rows.
If set to 1, do not output this keyword.
since_checkpoint If 1, translate entries since the last checkpoint only.
116
Chapter 3 The Database Tools Interface
Member Description
omit_comments If 1, omit comments.
replace Replace files without prompting for confirmation.
debug Reserved.
include_trigger_trans If 1, include trigger actions.
comment_trigger_trans If 1, include trigger actions as comments in the SQL
file.
since_time Translate entries only since the specified time.
a_truncate_log structure
Function Holds information needed for transaction log truncation using the DBTools
library.
Syntax typedef struct a_truncate_log {
unsigned short version;
const char * connectparms;
const char * startline;
MSG_CALLBACK errorrtn;
MSG_CALLBACK msgrtn;
char quiet : 1;
} a_truncate_log;
117
DBTools structures
an_unload_db structure
Function Holds information needed to unload a database using the DBTools library or
extract a remote database for SQL Remote. Those fields used by the dbxtract
SQL Remote extraction utility are indicated.
Syntax typedef struct an_unload_db {
unsigned short version;
const char * connectparms;
const char * startline;
const char * temp_dir;
const char * reload_filename;
MSG_CALLBACK errorrtn;
MSG_CALLBACK msgrtn;
MSG_CALLBACK statusrtn;
MSG_CALLBACK confirmrtn;
char unload_type;
char verbose;
char unordered : 1;
char no_confirm : 1;
char use_internal_unload : 1;
char dbo_avail : 1;
118
Chapter 3 The Database Tools Interface
char extract : 1;
char table_list_provided : 1;
char exclude_tables : 1;
char more_flag_bits_present : 1;
a_sysinfo sysinfo;
const char * remote_dir;
const char * dbo_username;
const char * subscriber_username;
const char * publisher_address_type;
const char * publisher_address;
unsigned short isolation_level;
char start_subscriptions : 1;
char exclude_foreign_keys : 1;
char exclude_procedures : 1;
char exclude_triggers : 1;
char exclude_views : 1;
char isolation_set : 1;
char include_where_subscribe : 1;
p_name table_list;
unsigned short escape_char_present : 1;
unsigned short view_iterations_present : 1;
unsigned short view_iterations;
char escape_char;
} an_unload_db;
Parameters Member Description
version DBTools version number.
connectparms The parameters needed to connect to the database.
They take the form of connection strings, such as the
following:
"UID=DBA;PWD=SQL;DBF=c:\asa6\asademo.db
"
$ For the full range of connection string options,
see "Connection parameters" on page 60 of the book
ASA User’s Guide.
startline The command line used to start the database engine.
The following is an example start line:
"c:\asa6\win32\dbeng7.exe"
The default start line is used if this member is NULL.
confirmrtn Callback routine for confirming an action.
errorrtn Callback routine for handling an error message.
msgrtn Callback routine for handling an information
message.
statusrtn Callback routine for handling a status message.
119
DBTools structures
Member Description
unload_type A member of the "dbunload type enumeration" on
page 126
verbose Operate in verbose mode.
unordered If 1, output the data unordered.
no_confirm If 1, operate without confirming actions.
use_internal_unload If 1, use the UNLOAD TABLE unloading. Of 0, use
the Interactive SQL OUTPUT statement.
dbo_avail Set to 1. Indicates that the version of DBTools is
recent enough to support the dbo_username field.
extract If 1 carry out a SQL Remote extraction. Otherwise
carry out an unload.
table_list_provided If 1, a table list is provided. Unload data for those
tables only.
exclude_tables If 1, exclude data for the listed tables.
more_flag_bits_present Set to 1. Indicates that the version of DBTools is
recent enough to support the dbo_username field.
sysinfo Pointer to a_sysinfo structure.
remote_dir If extracting a database, the directory for remote
users.
dbo_username Username for the dbo user.
subscriber_username If extracting a database, the user name of the
subscriber.
publisher_address_type If extracting a database, the message type for the
publisher.
publisher_address If extracting a database, the address for the publisher.
isolation_level If extracting a database, perform the extraction at the
specified isolation level.
start_subscriptions If extracting a database, start the subscription.
exclude_foreign_keys If extracting a database, exclude foreign key
definitions.
exclude_procedures If extracting a database, exclude procedures.
exclude_triggers If extracting a database, exclude triggers.
exclude_views If extracting a database, exclude views.
isolation_set Set to 1 if the isolation level is set
include_where_subscribe If extracting a database, extract fully qualified
publications and subscriptions.
120
Chapter 3 The Database Tools Interface
Member Description
table_list Pointer to a linked list of table names.
escape__present Set to 1 if a non-default escape character is being
specified.
view_iterations_present Set to 1. Indicates that the version of DBTools is
recent enough to support the view iterations option.
view_iterations If your database contains view definitions that are
dependent on each other, 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.
escape_char Escape character.
an_upgrade_db structure
Function Holds information needed to upgrade a database using the DBTools library.
Syntax typedef struct an_upgrade_db {
unsigned short version;
const char * connectparms;
const char * startline;
MSG_CALLBACK errorrtn;
MSG_CALLBACK msgrtn;
MSG_CALLBACK statusrtn;
char quiet : 1;
char dbo_avail : 1;
const char * dbo_username;
} an_upgrade_db;
121
DBTools structures
a_validate_db structure
Function Holds information needed for database validation using the DBTools library.
Syntax typedef struct a_validate_db {
unsigned short version;
const char * connectparms;
const char * startline;
p_name tables;
MSG_CALLBACK errorrtn;
MSG_CALLBACK msgrtn;
MSG_CALLBACK statusrtn;
char quiet : 1;
} a_validate_db;
122
Chapter 3 The Database Tools Interface
a_writefile structure
Function Holds information needed for database write file management using the
DBTools library.
Syntax typedef struct a_writefile {
unsigned short version;
const char * writename;
const char * wlogname;
const char * dbname;
const char * forcename;
MSG_CALLBACK confirmrtn;
MSG_CALLBACK errorrtn;
MSG_CALLBACK msgrtn;
char action;
char quiet : 1;
char erase : 1;
char force : 1;
123
DBTools structures
char mirrorname_present : 1;
const char * wlogmirrorname;
} a_writefile;
Parameters Member Description
version DBTools version number.
writename Write file name.
wlogname Used only when creating write files.
dbname Used when changing and creating write files.
forcename Forced file name reference.
confirmrtn Callback routine for confirming an action. Only used
when creating a write file.
errorrtn Callback routine for handling an error message.
msgrtn Callback routine for handling an information message.
action Reserved for use by Sybase.
quiet Operate without printing messages (1), or print messages
(0).
erase Used for creating write files only. Erase without
confirmation (1) or with confirmation (0).
force If 1, force the write file to point to a named file.
mirrorname_present Used when creating only. Set to 1. Indicates that the
version of DBTools is recent enough to support the
mirrorname field.
wlogmirrorname Name of the transaction log mirror.
124
Chapter 3 The Database Tools Interface
Verbosity enumeration
Function Specifies the volume of output.
Syntax enum {
VB_QUIET,
VB_NORMAL,
VB_VERBOSE
};
Parameters Value Description
VB_QUIET No output
VB_NORMAL Normal amount of output
VB_VERBOSE Verbose output, useful for debugging.
125
DBTools enumeration types
dbtran_userlist_type enumeration
Function The type of a user list, as used by an "a_translate_log structure" on page 116.
Syntax typedef enum dbtran_userlist_type {
DBTRAN_INCLUDE_ALL,
DBTRAN_INCLUDE_SOME,
DBTRAN_EXCLUDE_SOME
} dbtran_userlist_type;
Value Description
DBTRAN_INCLUDE_ALL Include operations from all users
DBTRAN_INCLUDE_SOME Include operations only from the users listed
in the supplied user list.
DBTRAN_EXCLUDE_SOME Exclude operations from the users listed in the
supplied user list.
Value Description
UNLOAD_ALL Unload both data and schema.
UNLOAD_DATA_ONLY Unload data. Do not unload schema.
UNLOAD_NO_DATA Unload schema only.
126
C H A P T E R 4
ODBC Programming
About this chapter The Open Database Connectivity (ODBC) interface is a programming
language interface defined by Microsoft Corporation as a standard interface
to database-management systems in the Windows and Windows NT
environments.
This chapter presents information for those who use the ODBC interface
directly. Users of application development systems that already have ODBC
support do not need to read this chapter.
The primary documentation for ODBC application development is the
ODBC SDK, available from Microsoft. This chapter describes features
specific to Adaptive Server Anywhere, but is not an exhaustive guide to
ODBC application programming.
Contents
Topic Page
Introduction to ODBC programming 128
ODBC fundamentals 130
Error checking 133
Using prepared statements 135
Working with result sets 137
Calling stored procedures 139
A sample program 141
Using ODBC without the driver manager 143
Using ODBC on Windows CE 145
127
Introduction to ODBC programming
ODBC conformance
Adaptive Server Anywhere provides support for ODBC 3.51 on
Windows 95/98, Windows NT, and Windows CE. Adaptive Server
Anywhere supports ODBC version 2.5 on Windows 3.1.
Levels of ODBC ODBC features are arranged according to a level of conformance. Features
support are either Core, Level 1, or Level 2, with level 2 being the most complete
level of ODBC support. These features are listed in the ODBC Programmer’s
Reference, which is available from Microsoft Corporation as part of the
ODBC software development kit or from the Microsoft Web site, at the
following Web site:
http://www.microsoft.com/data/odbc
128
Chapter 4 ODBC Programming
ODBC backwards Applications developed using older versions of ODBC will continue to work
compatibility with Adaptive Server Anywhere and the newer ODBC driver manager. The
new ODBC features are not provided for older applications.
The ODBC driver The ODBC driver manager is part of the ODBC software supplied with
manager Adaptive Server Anywhere. The ODBC Version 3 driver manager has a new
interface for configuring ODBC data sources.
129
ODBC fundamentals
ODBC fundamentals
Database access in ODBC is carried out 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.
ODBC Version 3.x In ODBC version 3.x, all objects are allocated using the function
SQLAllocHandle. SQLAllocHandle takes three parameters: the object
being allocated, the parent object, and a pointer to the location of the handle
to be allocated. An environment handle may be allocated as follows:
MyEnvironment = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv );
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, which is part of the
ODBC SDK.
ODBC Version 2.x ♦ Environment Every ODBC application must allocate exactly one
environment upon starting and free it at the end. With ODBC version
2.x, environments are allocated using SQLAllocEnv, and freed using
SQLFreeEnv.
♦ 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.
130
Chapter 4 ODBC Programming
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 your Adaptive Server Anywhere
installation directory.
Once your program has been compiled, you must link with the appropriate
import library file to have access to the ODBC functions:
♦ Windows 95/98 and Windows NT wodbc32.lib, which defines the
entry points into the Driver Manager odbc32.dll. If you connect to a
database in Windows NT, odbc32.dll will load the ODBC driver,
dbodbc7.dll.
♦ UNIX dbodbc.lib, which defines the entry points into the Adaptive
Server Anywhere ODBC driver, dbodbc7.so.
♦ Windows CE There is no ODBC driver manager for Windows CE.
ODBC applications should link against the supplied imports library
(dbodbc7.lib for ASCII characters or dbuodbc6.lib for Unicode). The
sample program (odbc.c) uses a File Data Source called ASA 7.0
Sample.dsn to connect to the database. You can create File Data Sources
using the ODBC Driver Manager on your desktop system, then copy the
file to the CE device. You can also edit File DSN’s with a text editor.
A first example
The following is a simple ODBC program:
{
HENV env;
HDBC dbc;
HSTMT stmt;
SQLAllocEnv( &env );
SQLAllocConnect( env, &dbc );
SQLConnect( dbc, "asademo", SQL_NTS,
"dba", SQL_NTS, "sql", SQL_NTS );
SQLSetConnectOption( dbc, SQL_AUTOCOMMIT, FALSE );
SQLAllocStmt( dbc, &stmt );
131
ODBC fundamentals
SQLDisconnect( dbc );
SQLFreeConnect( dbc );
SQLFreeEnv( env );
}
132
Chapter 4 ODBC 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 that 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; 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 that passes the same handle as a parameter.
Example The following program fragment uses SQLError and return codes:
HDBC dbc;
HSTMT stmt;
RETCODE retcode;
UCHAR errmsg[100];
. . .
133
Error checking
134
Chapter 4 ODBC Programming
retcode = SQLPrepare(hstmt,
"INSERT
INTO department
(dept_id, dept_name, dept_head_id )
VALUES (?, ?, ?,)",
SQL_NTS);
In this example:
♦ retcode Holds a return code that should be tested for success or
failure of the operation.
♦ hstmt Provides a handle to the statement, so that it can be
referenced later.
♦ ? The question marks are placeholders for statement parameters.
2 You set statement parameter values using SQLBindParameter. For
example, the following function call sets the value of the dept_id
variable:
SQLBindParameter(hstmt,
1,
SQL_PARAM_INPUT,
SQL_C_SSHORT,
SQL_INTEGER,
0,
0,
&sDeptID,
0,
&cbDeptID);
In this example:
♦ hstmt is the statement handle
135
Using prepared statements
♦ 1 indicates that this call sets the value of the first placeholder.
♦ SQL_PARAM_INPUT indicates that the parameter is an input
statement.
♦ SQL_C_SHORT and SQL_INTEGER indicate the C data type
being used in the application and the SQL type being used in the
database.
♦ The next two parameters indicate the column precision and the
number of decimal digits: both zero for integers.
♦ &sDeptID is a pointer to a buffer for the parameter value.
♦ The following zero indicates the length of the buffer, in bytes.
♦ &cbDeptID is a pointer to a buffer for the length of the parameter
value.
3 Bind the other two parameters and assign values to sDeptId:
4 Execute the statement:
retcode = SQLExecute(hstmt);
This step can be carried out multiple times.
5 Drop the statement. This frees resources associated with the statement
itself. You drop statements using SQLFreeStmt.
136
Chapter 4 ODBC Programming
for(;;) {
retcode = SQLFetch( stmt );
if( retcode == SQL_NO_DATA_FOUND ) break;
print_employee( emp_id, emp_lname);
}
137
Working with result sets
Notes ODBC documentation suggests that you use SELECT... FOR UPDATE to
indicate that a query is updateable using positioned operations. You do not
need to use the FOR UPDATE clause in Adaptive Server Anywhere;
SELECT statements are automatically updateable as long as the underlying
query supports updates. That is to say, as long as a data modification
statement on the columns in the result is meaningful, then positioned data
modification statements can be carried out on the cursor.
ODBC version 3.0 and later provides a cursor type called a block cursor.
When you use a block cursor, you can use SQLFetch to fetch a block of
rows, rather than a single row.
There are two alternatives for carrying out positioned updates and deletes in
ODBC. You can send positioned UPDATE and DELETE statements using
SQLExecute or you can use SQLSetPos to carry out the operation.
Depending on the parameters supplied (SQL_POSITION, SQL_REFRESH,
SQL_UPDATE, SQL_DELETE) SQLSetPos sets the cursor position and
allows an application to refresh data, or update or delete data in the result set.
With Adaptive Server Anywhere, you should use SQLSetPos to carry out
positioned operations on cursors.
The number of row positions you can fetch in a cursor is governed by the
size of an integer. You can fetch rows numbered up to number 2147483646,
which is one less than the value that can be held in an integer. When using
negative numbers (rows from the end) you can fetch down to one more than
the largest negative value that can be held in an integer.
Bookmarks and ODBC provides bookmarks, which are values used to identify rows in a
cursors cursor. Adaptive Server Anywhere supports bookmarks for all kinds of
cursor except dynamic cursors.
Before ODBC 3.0, a database could specify only whether it supports
bookmarks or not: there was no interface to provide this information for each
cursor type. There was no way for a database server to indicate for what kind
of cursor bookmarks were supported. For ODBC 2 applications, Adaptive
Server Anywhere returns that it does support bookmarks. There is therefore
nothing to prevent you from trying to use bookmarks with dynamic cursors;
however, you should not use this combination.
138
Chapter 4 ODBC Programming
/* Create a procedure */
SQLAllocStmt( dbc, &stmt );
SQLExecDirect( stmt,
"CREATE PROCEDURE Increment( INOUT a INT )" \
" BEGIN" \
" SET a = a + 1" \
" END", SQL_NTS );
139
Calling stored procedures
An example with a The following example calls a procedure that returns a result set. In the
result set example, the variable num_col will have the value 2, since the procedure
returns a result set with two columns. Again, error checking has been
omitted, to make the example easier to read.
HDBC dbc;
HSTMT stmt;
SWORD num_col;
RETCODE retcode;
char emp_id[ 10 ];
char emp_lame[ 20 ];
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 );
}
}
140
Chapter 4 ODBC Programming
A sample program
A sample ODBC program, odbc.c, is supplied in the cxmp subdirectory of
the Adaptive Server Anywhere installation directory. The program performs
the same actions as the Embedded SQL dynamic cursor example program.
$ For a description of the associated Embedded SQL program, see
"Database examples" on page 74.
Building the Along with the sample program is a batch file, makeall.bat, that can be used
sample program to compile the sample program for the various environments and compilers
supported by Adaptive Server Anywhere. For UNIX, use the shell script
makeall. The format of the command is as follows:
makeall odbc {Platform} {Compiler}
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 must be WINNT, to compile for Windows NT or Windows 95/98.
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
Building the The example program odbc.c, when compiled for Windows NT, runs
sample program as optionally as a service.
an NT 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 either as a regular executable or as an NT service.
141
A sample program
This example has been tested with the Watcom C/C++ 10.5 compiler and the
Microsoft Visual C++ 2.0 compiler.
142
Chapter 4 ODBC Programming
The libraries with the _r are for use with multi-threaded applications. If you
are developing single-threaded applications, use the library without the _r.
If you want to use the Adaptive Server Anywhere ODBC driver without an
ODBC driver manager you can do so, but you can then access only Adaptive
Server Anywhere data sources. The libraries are installed as symbolic links
to the shared library with a version number (in parentheses).
Data source If an ODBC driver manager is present, Adaptive Server Anywhere queries
information the driver manager for data source information. If Adaptive Server
Anywhere does not detect the presence of an ODBC driver manager, it uses
~/.odbc.ini for data source information.
144
Chapter 4 ODBC Programming
145
Using ODBC on Windows CE
146
C H A P T E R 5
About this chapter This chapter describes how to use the OLE DB interface to Adaptive Server
Anywhere.
Many applications that use the OLE DB interface do so through the
Microsoft ActiveX Data Objects (ADO) programming model, rather than
directly. This chapter describes ADO programming with Adaptive Server
Anywhere.
Contents
Topic Page
Introduction to OLE DB 148
ADO programming with Adaptive Server Anywhere 150
Supported OLE DB interfaces 157
147
Introduction to OLE DB
Introduction to OLE DB
OLE DB is a data access model from Microsoft. It uses the Component
Object Model (COM) interfaces and, unlike ODBC, OLE DB does not
assume that the data source uses a SQL query processor.
Adaptive Server Anywhere includes an OLE DB provider named
ASAProv. This provider is available for current Windows platforms as well
as the upcoming version of Windows CE that will support OLE DB.
You can also access Adaptive Server Anywhere using the Microsoft
OLE DB Provider for ODBC (MSDASQL), together with the Adaptive
Server Anywhere ODBC driver.
Using the Adaptive Server Anywhere OLE DB provider brings several
benefits:
♦ Some features, such as updating through a cursor, are not available using
the OLE DB/ODBC bridge.
♦ If you use the Adaptive Server Anywhere OLE DB provider, ODBC is
not required in your deployment.
♦ MSDASQL allows OLE DB clients to work with any ODBC driver but
does not guarantee that you can use the full range of functionality of
each ODBC driver. By using the Adaptive Server Anywhere provider,
you can get full access to Adaptive Server Anywhere features from
OLE DB programming environments.
Supported platforms
The Adaptive Server Anywhere OLE DB provider is designed to work with
OLE DB 2.5 and later. For Windows CE and its successors, the OLE DB
provider is designed for ADOCE 3.0 and later.
ADOCE is the Microsoft ADO for Windows CE SDK, and provides
database functionality for applications developed with the Windows CE
Toolkits for Visual Basic 5.0 and Visual Basic 6.0.
Adaptive Server Anywhere supports Windows CE version 2.11. It does not
support Windows CE version 2.0. Windows CE 2.11 includes a version of
ADOCE lower than 3.0, which is considerably more restricted, and is not
supported by the Adaptive Server Anywhere OLE DB driver.
148
Chapter 5 The OLE DB and ADO Programming Interfaces
Distributed transactions
The OLE DB driver can be used as a resource manager in a distributed
transaction environment. For more information, see "Three-tier Computing
and Distributed Transactions" on page 917 of the book ASA User’s Guide.
149
ADO programming with Adaptive Server Anywhere
150
Chapter 5 The OLE DB and ADO Programming Interfaces
151
ADO programming with Adaptive Server Anywhere
’Execute a command
myCommand.CommandText = _
"update customer set fname=’Liz’ where id=102"
Set myCommand.ActiveConnection = myConn
myCommand.Execute cAffected
MsgBox CStr(cAffected) +
" rows affected.", vbInformation
myConn.Close
End Sub
’ Declare variables
Dim myConn As New ADODB.Connection
Dim myCommand As New ADODB.Command
Dim myRS As New ADODB.Recordset
152
Chapter 5 The OLE DB and ADO Programming Interfaces
myRS.Close
myConn.Close
End Sub
Notes The Recordset object in this example holds the results from a query on the
Customer table. The For loop scrolls through the first several rows and
displays the company_name value for each row.
This is a simple example of using a cursor from ADO. For more advanced
examples, see "Working with Recordset object" on page 153.
153
ADO programming with Adaptive Server Anywhere
154
Chapter 5 The OLE DB and ADO Programming Interfaces
myConn.BeginTrans
SQLString = "Select * from customer"
myRS.Open SQLString, _
myConn, adOpenDynamic, adLockBatchOptimistic
Using transactions
By default, any change you make to the database using ADO is committed as
soon as it is executed. This includes explicit updates, as well as the
UpdateBatch method on a Recordset. However, the previous section
illustrated that you can use the BeginTrans and RollbackTrans or
CommitTrans methods on the Connection object to use transactions.
155
ADO programming with Adaptive Server Anywhere
156
Chapter 5 The OLE DB and ADO Programming Interfaces
157
Supported OLE DB interfaces
158
Chapter 5 The OLE DB and ADO Programming Interfaces
159
Supported OLE DB interfaces
160
Chapter 5 The OLE DB and ADO Programming Interfaces
161
Supported OLE DB interfaces
162
C H A P T E R 6
About this chapter This chapter describes the Open Client programming interface for Adaptive
Server Anywhere.
The primary documentation for Open Client application development is the
Open Client documentation, available from Sybase. This chapter describes
features specific to Adaptive Server Anywhere, but it is not an exhaustive
guide to Open Client application programming.
Contents
Topic Page
What you need to build Open Client applications 164
Data type mappings 165
Using SQL in Open Client applications 167
Known Open Client limitations of Adaptive Server Anywhere 170
163
What you need to build Open Client applications
164
Chapter 6 The Open Client Interface
165
Data type mappings
In most cases, the Open Client data type is mapped to a Adaptive Server
Anywhere data type that has a greater range of possible values. As a result, it
is possible to pass a value to Adaptive Server Anywhere that will be accepted
and stored in a database, but one that is too large to be fetched by an Open
Client application.
Data type Open Client Open Client ASA lower ASA upper
lower range upper range range range
MONEY –922 377 203 922 377 203 –1e15 + 0.0001 1e15 – 0.0001
685 477.5808 685 477.5807
SMALLMONEY –214 748.3648 214 748.3647 –214 748.3648 214 748.3647
DATETIME Jan 1, 1753 Dec 31, 9999 Jan 1, 0001 Dec 31, 9999
SMALLDATETIME Jan 1, 1900 June 6, 2079 March 1, 1600 Dec 31, 7910
Example For example, the Open Client MONEY and SMALLMONEY data types do
not span the entire numeric range of their underlying Adaptive Server
Anywhere implementations. Therefore it is possible to have a value in a
Adaptive Server Anywhere column which exceeds the boundaries of the
Open Client data type MONEY. When the client fetches any such offending
values via Adaptive Server Anywhere, an error is generated.
Timestamps The Adaptive Server Anywhere implementation of the Open Client
TIMESTAMP data type, when such a value is passed in Adaptive Server
Anywhere is different from that of Adaptive Server Enterprise. In Adaptive
Server Anywhere the value is mapped to the Adaptive Server Anywhere
DATETIME data type. The default value is NULL in Adaptive Server
Anywhere, and no guarantee is made of its uniqueness. By contrast,
Adaptive Server Enterprise ensures that the value is monotonically
increasing in value, and so is unique.
By contrast, the Adaptive Server Anywhere TIMESTAMP data type contains
year, month, day, hour, minute, second, and fraction of second information.
In addition, the DATETIME data type has a greater range of possible values
than the Open Client data types that are mapped to it by Adaptive Server
Anywhere.
166
Chapter 6 The Open Client Interface
167
Using SQL in Open Client applications
Using cursors
The ct_cursor function is used to manage cursors. This function takes a
type parameter which describes the action you are taking.
Supported cursor Not all the types of cursor that Adaptive Server Anywhere supports are
types available through the Open Client interface. You cannot use scroll cursors,
dynamic scroll cursors, and insensitive cursors through Open Client.
Uniqueness and updateability are two properties of cursors. Cursors can be
unique (each row carries primary key or uniqueness information, regardless
of whether it is used by the application) or not. Cursors can be read only or
updateable. If a cursor is updateable and not unique, performance may suffer,
as no prefetching of rows is done in this case, regardless of the
CS_CURSOR_ROWS setting (see below).
The steps in using In contrast to some other interfaces, such as Embedded SQL, Open Client
cursors associates a cursor with a SQL statement expressed as a string. Embedded
SQL first prepares a statement, and then the cursor is declared using the
statement handle.
168
Chapter 6 The Open Client Interface
6 In Open Client, you also need to deallocate the resources associated with
a cursor. You do this using ct_cursor with CS_CURSOR_DEALLOC.
You can also use CS_CURSOR_CLOSE with the additional parameter
CS_DEALLOC to carry out these operations in a single step.
169
Known Open Client limitations of Adaptive Server Anywhere
170
Index
array fetches
about, 36
asademo.db file
A about, x
a_backup_db structure, 102 ASAProv
a_change_log structure, 104 OLE DB provider, 148
a_compress_db structure, 105 autocommit
a_compress_stats structure, 106 ODBC, 131
a_create_db structure, 107
a_db_collation structure, 109
a_db_info structure, 110
a_dbtools_info structure, 111 B
a_name structure, 113 background processing
a_stats_line structure, 114 callback functions, 67
a_sysinfo structure, 114 backup functions
a_table_info structure, 115 about, 63
a_translate_log structure, 116 backups
a_truncate_log structure, 117 Embedded SQL functions, 63
a_validate_db structure, 122 BINARY data types
a_writefile structure, 123 Embedded SQL, 21
ActiveX Data Objects bind variables
about, 150 about, 40
ADO bit fields
about, 150 using, 90
Command object, 151 Blank padding enumeration, 125
commands, 151 bookmarks
Connection object, 150 cursors, 138
connections, 150 Borland C++
cursors, 154 support, 8
queries, 152, 153
Recordset object, 152, 153
updates, 154
alloc_sqlda function, 62 C
alloc_sqlda_noind function, 62 C
an_erase_db structure, 112 data types, 21
an_expand_db structure, 113 callback functions
an_unload_db structure, 118 Embedded SQL, 67
an_upgrade_db structure, 121 registering, 68
ARRAY clause capabilities
FETCH statement, 36 supported, 170
character strings, 81
171
D–D
CLOSE statement
about, 33
D
data type conversion
Command object
indicator variables, 25
ADO, 151
data types
commands
C data types, 21
ADO Command object, 151
dynamic SQL, 44
compile and link process, 9
Embedded SQL, 17
compilers
host variables, 21
supported, 8
mapping, 165
Connection object
Open Client, 165
ADO, 150
ranges, 165
connections
SQLDA, 46
ADO Connection object, 150
database servers
functions, 57
functions, 57
ODBC, 130
database tools interface
conventions
a_backup_db structure, 102
documentation, vii
a_change_log structure, 104
conversion
a_compress_db structure, 105
data types, 25
a_compress_stats structure, 106
CS_CSR_ABS, 170
a_create_db structure, 107
CS_CSR_FIRST, 170
a_db_collation structure, 109
CS_CSR_LAST, 170
a_db_info structure, 110
CS_CSR_PREV, 170
a_dbtools_info structure, 111
CS_CSR_REL, 170
a_name structure, 113
CS_DATA_BOUNDARY, 170
a_stats_line structure, 114
CS_DATA_SENSITIVITY, 170
a_sysinfo structure, 114
CS_PROTO_DYNPROC, 170
a_table_info structure, 115
CS_REG_NOTIF, 170
a_translate_log structure, 116
CS_REQ_BCP, 170
a_truncate_log structure, 117
ct_command function
a_validate_db structure, 122
Open Client, 167, 169
a_writefile structure, 123
ct_cursor function
about, 83
Open Client, 168
an_erase_db structure, 112
ct_dynamic function
an_expand_db structure, 113
Open Client, 167
an_unload_db structure, 118
ct_results function
an_upgrade_db structure, 121
Open Client, 169
Blank padding enumeration, 125
ct_send function
DBBackup function, 93
Open Client, 169
DBChangeLogName function, 93
cursors
DBChangeWriteFile function, 94
bookmarks, 138
DBCollate function, 94
canceling, 67
DBCompress function, 94
delete, 169
DBCreate function, 95
Embedded SQL, 33
DBCreateWriteFile function, 95
example C code, 74
DBErase function, 96
ODBC, 137
DBExpand function, 96
Open Client, 168
DBInfo function, 96
stored procedures, 53
DBInfoDump function, 97
update, 169
DBInfoFree function, 97
updating, 154
DBStatusWriteFile function, 98
172
D–D
173
E–F
174
G–M
175
N–P
O
ODBC P
backwards compabitility, 129 performance
compabitility, 129 prepared statements, 135
compiling, 130 place holders
conformance, 128 dynamic SQL, 40
cursors, 137 PREPARE statement, 40
error checking, 133 PREPARE TRANSACTION statement
example application, 131 and Open Client, 170
example program, 141 prepared statements
fundamentals, 130 ODBC, 135
introduction, 128 Open Client, 167
linking, 130 preprocessor
multiple result sets, 139 about, 8
multi-threaded applications, 132 running, 10
176
Q–S
procedures software
Embedded SQL, 52 return codes, 87
ODBC, 139 SQL
result sets, 53 SQL/92 syntax, 80
program structure SQL Communications Area
Embedded SQL, 12 about, 27
PUT statement SQL preprocessor
multi-row, 36 about, 79
wide, 36 command line, 79
running, 10
SQL statements
executing, 167
Q SQL/92
queries conformance, 80
ADO Recordset object, 152, 153 SQL_CALLBACK type declaration, 68
single-row, 32 SQL_CALLBACK_PARM type declaration, 68
quoted identifiers SQL_ERROR, 133
sql_needs_quotes function, 70 SQL_INVALID_HANDLE, 133
SQL_NEED_DATA, 133
sql_needs_quotes function, 70
SQL_NO_DATA_FOUND, 133
R SQL_SUCCESS, 133
Rapier devices SQL_SUCCESS_WITH_INFO, 133
Windows CE, 149 SQLBindCol function
Recordset object ODBC, 137
ADO, 152, 153 SQLCA
request processing about, 27
Embedded SQL, 67 changing, 29
requests fields, 27
aborting, 67 multiple, 30
result sets threads, 29
ADO Recordset object, 152, 153 sqlcabc
multiple, and ODBC, 139 SQLCA field, 27
ODBC, 137, 139 sqlcaid
Open Client, 169 SQLCA field, 27
stored procedures, 53 sqlcode
return codes, 87 SQLCA field, 27
sqld field
SQLDA, 45
SQLDA
S about, 40, 44
sample database allocating, 61, 62
about, x filling, 62
SELECT statement freeing, 63
dynamic, 42 length field, 47
single row, 32 strings, 62
servers SQLDA fields
locating, 59 about, 45
services sqlda_storage function, 62
example code, 78, 141 sqlda_string_length function, 62
177
T–W
sqldabc field
SQLDA, 45
T
threads
sqldaif field
Embedded SQL, 29, 30
SQLDA, 45
multiple, 128
sqldata field
ODBC applications, 132
SQLDA, 46
UNIX development, 143
sqldef.h
TIMESTAMP data type
data types, 17
conversion, 165
sqlerrd
transactions
SQLCA field, 27
ODBC, 131
sqlerrmc
truncation
SQLCA field, 27
FETCH statement, 25
sqlerrml
indicator variables, 25
SQLCA field, 27
on FETCH, 25
sqlerror_message, 70
two-phase commit
sqlerrp
and Open Client, 170
SQLCA field, 27
SQLGetData function
ODBC, 137
sqlind field
SQLDA, 46
U
Unicode
sqllen ODBC, 145
SQLDA, 47 Windows CE, 145
sqllen field UNIX
SQLDA, 46 ODBC, 131, 143
sqlname updates
SQLDA field, 44 cursor, 154
sqlname field utilities
SQLDA, 46 SQL preprocessor, 79
SQLPP
about, 8
command line, 79
sqlstate, 28 V
sqltype field VARCHAR data type
SQLDA, 46 Embedded SQL, 21
sqlvar field verbosity enumeration, 125
contents, 46 version 7.0
SQLDA, 45 new features, 147
sqlwarn, 28 Visual C++
statements support, 8
ODBC, 130
static SQL, 40
stored procedures
Embedded SQL, 52 W
result sets, 53 Watcom C/C++
string support, 8
data type, 62 wide fetches
structure packing about, 36
header files, 10 wide inserts, 36
supported platforms wide puts, 36
OLE DB, 148
178
W–W
179
W–W
180