Iqpprog
Iqpprog
Programming iii
Contents
Column Subset
(a_v4_extfn_col_subset_of_input) ...................25
Describe API ........................................................25
Describe Column Type
(a_v4_extfn_describe_col_type) .....................90
Describe Parameter Type
(a_v4_extfn_describe_parm_type) ..................91
Describe Return (a_v4_extfn_describe_return)
.........................................................................93
Describe UDF Type
(a_v4_extfn_describe_udf_type) .....................95
Execution State (a_v4_extfn_state) .....................95
External Function (a_v4_extfn_proc) ...................97
External Procedure Context
(a_v4_extfn_proc_context) ............................100
License Information (a_v4_extfn_license_info) . .112
Optimizer Estimate (a_v4_extfn_estimate) ........113
Order By List (a_v4_extfn_orderby_list) ............113
Partition By Column Number
(a_v4_extfn_partitionby_col_num) ................114
Row (a_v4_extfn_row) .......................................115
Row Block (a_v4_extfn_row_block) ...................116
Table (a_v4_extfn_table) ....................................116
Table Context (a_v4_extfn_table_context) .........117
Table Functions (a_v4_extfn_table_func) .........124
Using SQL in Applications ................................................131
SQL statement execution in applications ....................131
Prepared statements ..................................................132
Prepared Statements Overview .........................133
Cursor usage ..............................................................135
Cursors ..............................................................135
Benefits of using cursors ...................................136
Cursor principles .........................................................137
Cursor positioning ..............................................138
Cursor behavior when opening cursors .............138
iv SAP Sybase IQ
Contents
Programming v
Contents
vi SAP Sybase IQ
Contents
Programming vii
Contents
Programming ix
Contents
x SAP Sybase IQ
Contents
Programming xi
Contents
Programming xiii
Contents
Programming xv
Contents
Programming xvii
Contents
sasql_pconnect ..................................................576
sasql_prepare ....................................................576
sasql_query .......................................................576
sasql_real_escape_string ..................................577
sasql_real_query ...............................................577
sasql_result_all ..................................................578
sasql_rollback ....................................................579
sasql_set_option ................................................579
sasql_stmt_affected_rows .................................580
sasql_stmt_bind_param .....................................580
sasql_stmt_bind_param_ex ...............................581
sasql_stmt_bind_result ......................................582
sasql_stmt_close ...............................................582
sasql_stmt_data_seek .......................................582
sasql_stmt_errno ...............................................583
sasql_stmt_error ................................................583
sasql_stmt_execute ...........................................583
sasql_stmt_fetch ................................................584
sasql_stmt_field_count ......................................584
sasql_stmt_free_result .......................................584
sasql_stmt_insert_id ..........................................585
sasql_stmt_next_result ......................................585
sasql_stmt_num_rows .......................................586
sasql_stmt_param_count ...................................586
sasql_stmt_reset ................................................586
sasql_stmt_result_metadata ..............................587
sasql_stmt_send_long_data ..............................587
sasql_stmt_store_result .....................................587
sasql_store_result ..............................................588
sasql_sqlstate ....................................................588
sasql_use_result ................................................589
Ruby Support .....................................................................591
Ruby API Support .......................................................591
Configuring Rails Support in SAP Sybase IQ ....592
Ruby-DBI Driver .................................................595
Programming xix
Contents
xx SAP Sybase IQ
Contents
Programming xxi
Contents
Programming xxiii
Contents
Programming xxv
Contents
Partner Certifications
The SAP® Sybase® IQ partner ecosystem includes certified partners, data warehouse
infrastructure partners, analytics solutions partners, and business intelligence partner
applications.
For certification reports and the list of SAP Sybase IQ partners, see the SAP Sybase IQ
Marketplace.
Programming 1
Partner Certifications
2 SAP Sybase IQ
Platform Certifications
Platform Certifications
Certified means that a product runs on, and is supported on, a specific platform environment.
SAP Sybase IQ is certified on certain operating systems with specific CPU architecture
combinations.
Find certified product-platform combinations at http://certification.sybase.com/ucr/
search.do.
Programming 3
Platform Certifications
4 SAP Sybase IQ
SAP Sybase IQ as a Data Server for Client Applications
Network Services
Open Client network services include Sybase Net-Library, which provides support for
specific network protocols such as TCP/IP and DECnet. The Net-Library interface is invisible
to application developers. However, on some platforms, an application may need a different
Net-Library driver for different system network configurations. Depending on your host
Programming 5
SAP Sybase IQ as a Data Server for Client Applications
platform, the Net-Library driver is specified either by the system's Sybase configuration or
when you compile and link your programs.
Instructions for driver configuration can be found in the Open Client/Server Configuration
Guide.
Instructions for building Client-Library programs can be found in the Open Client/Server
Programmer's Supplement.
login_procedure option
Specifies a login procedure that sets connection compatibility options at startup.
Allowed values
String
Default
sp_login_environment system procedure
Scope
Can be set for an individual connection or for PUBLIC. You must have the SET ANY
SECURITY OPTION system privilege to set this option.
Remarks
This login procedure calls the sp_login_environment procedure at run time to determine the
database connection settings. The login procedure is called after all the checks have been
performed to verify that the connection is valid. The procedure specified by the
6 SAP Sybase IQ
SAP Sybase IQ as a Data Server for Client Applications
login_procedure option is not executed for event connections, but it is executed for web
service connections.
You can customize the default database option settings by creating a new procedure and
setting login_procedure to call the new procedure. This custom procedure needs to call either
sp_login_environment or detect when a TDS connection occurs (see the default
sp_login_environment code) and call sp_tsql_environment directly. Failure to do so can break
TDS-based connections. Do not edit either sp_login_environment or sp_tsql_environment.
A password expired error message with SQLSTATE 08WA0 can be signaled by a user-defined
login procedure to indicate to a user that their password has expired. Signaling the error allows
applications to check for the error and process expired passwords. It is recommended that you
use a login policy to implement password expiry and not a login procedure that returns the
expired password error message.
If you use the NewPassword=* connection parameter, signaling this error is required for the
client libraries to prompt for a new password. If the procedure signals SQLSTATE 28000
(invalid user ID or password) or SQLSTATE 08WA0 (expired password), or the procedure
raises an error with RAISERROR, the login fails and an error is returned to the user. If you
signal any other error or if another error occurs, then the user login is successful and a message
is written to the database server message log.
Example
The following example shows how you can disallow a connection by signaling the
INVALID_LOGON error.
CREATE PROCEDURE DBA.login_check( )
BEGIN
DECLARE INVALID_LOGON EXCEPTION FOR SQLSTATE '28000';
// Allow a maximum of 3 concurrent connections
IF( DB_PROPERTY( 'ConnCount' ) > 3 ) THEN
SIGNAL INVALID_LOGON;
ELSE
CALL sp_login_environment;
END IF;
END
go
The following example shows how you can block connection attempts if the number of failed
connections for a user exceeds 3 within a 30 minute period. All blocked attempts during the
block out period receive an invalid password error and are logged as failures. The log is kept
long enough for a DBA to analyze it.
CREATE TABLE DBA.ConnectionFailure(
pk INT PRIMARY KEY DEFAULT AUTOINCREMENT,
Programming 7
SAP Sybase IQ as a Data Server for Client Applications
8 SAP Sybase IQ
SAP Sybase IQ as a Data Server for Client Applications
The following example shows how to signal an error indicating that the user's password has
expired. It is recommended that you use a login policy to implement password expiry
notification.
CREATE PROCEDURE DBA.check_expired_login( )
BEGIN
DECLARE PASSWORD_EXPIRED EXCEPTION FOR SQLSTATE '08WA0';
Start the server and set up an alias for a particular database. The following command sets
live_sales equivalent to salesbase.db:
start_iq -n sales_live <other parameters> -x \ ‘tcpip{port=5555}’
salesbase.db -n live_sales
A server name may only appear once in the interfaces file. Because the connection to
SAP Sybase IQ is now based on the database name, the database name must be unique. If all
Programming 9
SAP Sybase IQ as a Data Server for Client Applications
your scripts are set up to work on salesbase database, you will not have to modify them to
work with live_sales or test_sales.
10 SAP Sybase IQ
Using In-Database Analytics in Applications
See also
• Appendix: Using OLAP on page 843
Programming 11
Using In-Database Analytics in Applications
Java UDFs
Java UDFs behave like SQL functions except that the code for the procedure or function is
written in Java, and the execution takes place outside the database server, within a Java VM
environment. You can define Java scalar UDFs, and Java table UDFs.
Java UDFs do not require a separately licensed SAP Sybase IQ option.
Table UDFs
Table UDFs are external user-defined C, C++, or Java table functions. Unlike scalar and
aggregate UDFs, table UDFs produce row sets as output. A SQL query can consume the row
sets as a table expression in the FROM clause of a SQL statement.
Scalar and aggregate UDFs can use either the v3 or v4 extfn API, but table UDFs can use only
v4.
See User-Defined Functions for detailed information and examples.
TPFs
Table parameterized functions (TPFs) are enhanced table UDFs that accept either scalar
values or row sets as input. You can configure user-specified partitioning for your TPF. The
UDF developer can declare a partitioning scheme that breaks down the dataset into smaller
pieces of query processing that you distribute across multiplex nodes. This enables you to
execute the TPF in parallel in a distributed server environment over partitions of row sets. The
query engine supports massive parallelization of TPF processing.
See User-Defined Functions for detailed information and examples.
12 SAP Sybase IQ
Using In-Database Analytics in Applications
Hadoop Integration
SAP Sybase IQ includes a UDF API that you can use to build MapReduce components, which
can be used for Hadoop integration. The SAP Sybase solutions store has examples of Hadoop
integration.
The MapReduce programming model is designed for massively parallel distributed
computing. The MapReduce programming model consists of two main stages:
• Map stage – The leader node divides a problem into subproblems or maps. These maps
must be independent of each other and are executed in parallel.
• Reduce stage – The leader node collects the answers of the subproblems and combines
them in a meaningful way to get the answer to the original problem.
Apache Hadoop is a MapReduce implementation. Hadoop is a Java software framework that
automates scheduling of map and reduce jobs.
SAP Sybase IQ supports Hadoop-like parallel scheduling using Table Parameterized
Functions (TPFs), a class of external user-defined functions. TPFs accept arbitrary rowsets of
table-valued input parameters, and can be parallized in a distributed server environment. You
can specify partitioning and ordering requirements on the TPF input. As a developer, you can
use TPFs to exploit the MapReduce paradigm from within the database server, using SQL.
For TPF fundamentals, see the User-Defined Functions guide.
Programming 13
Using In-Database Analytics in Applications
not production-grade and will require additional safeguards and testing prior to using in
production.
14 SAP Sybase IQ
Using In-Database Analytics in Applications
System.out.println(e.toString());
}
rset[0] = rs; // Assign result set to the 1st of the passé din
array.
in.close();
reader.close();
fileSystem.close();
}
}
}
2. Install the class or the packaged JAR file:
INSTALL JAVA NEW JAR ‘myjar’ FROM FILE ‘/home/mymachine/UDFs/
myjar.jar’;
3. Create the function:
CREATE or REPLACE PROCEDURE readFileByLine( IN fileName CHAR(50) )
RESULT ( c1 VARCHAR(255) )
EXTERNAL NAME 'example.HDFSclient.readFileByLine(Ljava/lang/
String;[Ljava/sql/ResultSet;)V'
LANGUAGE JAVA;
4. Execute the function:
SELECT c1 FROM readFileByLine('/home/mymachine/input/input.txt');
1. During the mapping step, each file is worked on as a separate map job and the output from
each of these maps is the following <key, value>:
• Job1: <Hello, one> <World, one> <Goodbye, one> <World, one>
• Job2: <Goodbye, one> <world, one> <Hadoop, one>
2. Call the Reducer which simply adds the <key, value> outputted from the Map step. Output
from the local Reducer is:
• Job1: <Hello, one> <World, two> <Goodbye, one>
• Job2: <Goodbye, one> <World, one> <Hadoop, one>
3. Combine to get the final output:
<Hello, one> <World, 3><Goodbye,2><Hadoop, 1>
Note: This sample code is primarily for illustration purposes and is not intended for
production. Although effort was made to ensure reasonable error handling, the examples are
Programming 15
Using In-Database Analytics in Applications
not production-grade and will require additional safeguards and testing prior to using in
production.
public class WordCountDriver extends Configured {
public static void String HADOOP_ROOT_DIR = “hdfs://localhost:
9000”
private Text word = new Text();
private final IntWritable one = new IntWritable(1);
// Specify a mapper
job.setMapperClass(WordCountDriver.WordCountMapper.class);
16 SAP Sybase IQ
Using In-Database Analytics in Applications
// Specify a reducer
job.setReducerClass(WordCountDriver.WordCountReducer.class);
job.setCombinerClass(WordCountDriver.WordCountReducer.class);
job.setJarByClass(WordCountDriver.class)
Blob (a_v4_extfn_blob)
Use the a_v4_extfn_blob structure to represent a free-standing blob object.
Implementation
typedef struct a_v4_extfn_blob {
a_sql_uint64 (SQL_CALLBACK *blob_length)(a_v4_extfn_blob *blob);
void (SQL_CALLBACK *open_istream)(a_v4_extfn_blob *blob,
a_v4_extfn_blob_istream **is);
void (SQL_CALLBACK *close_istream)(a_v4_extfn_blob *blob,
a_v4_extfn_blob_istream *is);
void (SQL_CALLBACK *release)(a_v4_extfn_blob *blob);
} a_v4_extfn_blob;
Method Summary
Method Name Data Type Description
blob_length a_sql_uint64 Returns the length, in
bytes, of the specified
blob.
Programming 17
Using In-Database Analytics in Applications
Description
The object a_v4_extfn_blob is used when:
• a table UDF needs to read LOB or CLOB data from a scalar input value
• a TPF needs to read LOB or CLOB data from a column in an input table
blob_length
Use the blob_length v4 API method to return the length, in bytes, of the specified blob.
Declaration
a_sql_uint64 blob_length(
a_v4_extfn_blob *
)
Usage
Returns the length, in bytes, of the specified blob.
Parameters
Parameter Description
blob The blob to return the length of.
Returns
The length of the specified blob.
See also
• open_istream on page 19
• close_istream on page 19
18 SAP Sybase IQ
Using In-Database Analytics in Applications
• release on page 20
open_istream
Use the open_istream v4 API method to open an input stream to read from a blob.
Declaration
void open_istream(
a_v4_extfn_blob *blob,
a_v4_extfn_blob_istream **is
)
Usage
Opens an input stream that can be used to begin reading from the specified blob.
Parameters
Parameter Description
blob The blob to open the input stream on.
Returns
Nothing.
See also
• blob_length on page 18
• close_istream on page 19
• release on page 20
close_istream
Use the close_istream v4 API method to close the input stream for the specified blob.
Declaration
void close_istream(
a_v4_extfn_blob *blob,
a_v4_extfn_blob_istream *is
)
Usage
Closes the input stream previously opened with the open_istream API.
Programming 19
Using In-Database Analytics in Applications
Parameters
Parameter Description
Returns
Nothing.
See also
• blob_length on page 18
• open_istream on page 19
• release on page 20
release
Use the release v4 API method to indicate that the caller is done with the currently selected
blob. Releasing enables the owner to free memory.
Declaration
void release(
a_v4_extfn_blob *blob
)
Usage
Indicates that the caller is done with this blob and that the blob owner is free to release
resources. After release(), referencing the blob results in an error. The owner usually deletes
the memory when release() is called.
Parameters
Parameter Description
blob The blob to release.
Returns
Nothing.
See also
• blob_length on page 18
• open_istream on page 19
• close_istream on page 19
20 SAP Sybase IQ
Using In-Database Analytics in Applications
Implementation
typedef struct a_v4_extfn_blob_istream {
size_t (SQL_CALLBACK *get)( a_v4_extfn_blob_istream *is, void
*buf, size_t len );
a_v4_extfn_blob *blob;
a_sql_byte *beg;
a_sql_byte *ptr;
a_sql_byte *lim;
} a_v4_extfn_blob_istream;
Method Summary
Method Name Data Type Description
get size_t Gets a specified
amount of data from a
blob input stream.
get
Use the get v4 API method to get a specified amount of data from a blob input stream.
Declaration
size_t get(
a_v4_extfn_blob_istream *is,
void *buf,
size_t len
Programming 21
Using In-Database Analytics in Applications
Usage
Gets a specified amount of data from a blob input stream.
Parameters
Parameter Description
is The input stream to retrieve data from.
Returns
The amount of data received.
Implementation
typedef struct a_v4_extfn_column_data {
a_sql_byte *is_null;
a_sql_byte null_mask;
a_sql_byte null_value;
void *data;
a_sql_uint32 *piece_len;
size_t max_piece_len;
void *blob_handle;
} a_v4_extfn_column_data;
is_null a_sql_byte * Points to a byte where the NULL information for the value is
stored.
null_mask a_sql_byte One or more bits used to represent the NULL value
22 SAP Sybase IQ
Using In-Database Analytics in Applications
data void * Pointer to the data for the column. Depending on the type of fetch
mechanism, either points to an address in the consumer, or an
address where the data is stored in the UDF.
piece_len a_sql_uint32 * The actual length of data for variable-length data types
max_piece_len size_t The maximum data length allowed for this column.
blob_handle void * A non-NULL value means that the data for this column must be
read using the blob API
Description
The a_v4_extfn_column_data structure represents the data values and related
attributes for a specific data column. This structure is used by the producer when generating
result set data. Data producers are also expected to create storage for data, piece_len, and the
is_null flag.
The is_null, null_mask, and null_value data members indicate null in a column, and handle
situations in which the null-bits are encoded into one byte for eight columns, or other cases in
which a full byte is used for each column.
This example shows how to interpret the three fields used to represent NULL: is_null,
null_mask, and null_value.
is_value_null()
return( (*is_null & null_mask) == null_value )
set_value_null()
*is_null = ( *is_null & ~null_mask) | null_value
set_value_not_null()
*is_null = *is_null & ~null_mask | (~null_value & null_mask)
Implementation
typedef struct a_v4_extfn_column_list {
a_sql_int32 number_of_columns;
a_sql_uint32 column_indexes[1]; // there are
number_of_columns entries
} a_v4_extfn_column_list;
Programming 23
Using In-Database Analytics in Applications
Description
The meaning of the contents of the column list changes, depending on whether the list is used
with TABLE_PARTITIONBY or TABLE_UNUSED_COLUMNS.
Implementation
typedef struct a_v4_extfn_order_el {
a_sql_uint32 column_index; // Index of the column in the
table (1-based)
a_sql_byte ascending; // Nonzero if the column
is ordered "ascending".
} a_v4_extfn_order_el;
Description
The a_v4_extfn_order_el structure describes a column and tells whether it should be
in ascending or descending order. The a_v4_extfn_orderby_list structure holds an
array of these structures. There is one a_v4_extfn_order_el structure for each column
in the ORDERBY clause.
24 SAP Sybase IQ
Using In-Database Analytics in Applications
Implementation
typedef struct a_v4_extfn_col_subset_of_input {
a_sql_uint32 source_table_parameter_arg_num; // arg_num of
the source table parameter
a_sql_uint32 source_column_number; // source column of
the source table
} a_v4_extfn_col_subset_of_input;
Description
The query optimizer uses the subset of input to infer logical properties of the values in the
output column. For example, the number of distinct values in the input column is an upper
bound on the distinct values in the output column, and any local predicates on the input column
also hold on the output column.
Describe API
The _describe_extfn function is a member of a_v4_extfn_proc. A UDF gets and sets
logical properties using the describe_column, describe_parameter, and
describe_udf properties in the a_v4_extfn_proc_context object.
_describe_extfn Declaration
void (UDF_CALLBACK *_describe_extfn)(a_v4_extfn_proc_context
*cntxt );
)
Usage
The _describe_extfn function describes the procedure evaluation to the server.
Each of the describe_column, describe_parameter, and describe_udf
properties has an associated get and set method, a set of attribute types, and an associated data
type for each attribute. The get methods retrieve information from the server; the set methods
describe the logical properties of the UDF (such as the number of output columns or the
number of distinct values for a output column) to the server.
Programming 25
Using In-Database Analytics in Applications
*describe_column_get
The describe_column_get v4 API method is used by the table UDF to retrieve
properties about an individual column of a TABLE parameter.
Declaration
a_sql_int32 (SQL_CALLBACK *describe_column_get)(
a_v4_extfn_proc_context *cntxt,
a_sql_uint32 arg_num,
a_sql_uint32 column_num,
a_v4_extfn_describe_parm_type describe_type,
void *describe_buffer,
size_t describe_buffer_len );
Parameters
Parameter Description
cntxt The procedure context object for this UDF.
Returns
On success, returns the number of bytes written to the describe_buffer. If an error occurs, or
no property is retrieved, this function returns one of the generic describe_column errors.
26 SAP Sybase IQ
Using In-Database Analytics in Applications
EXTFNAPIV4_DESCRIBE_COL_CONSTANT_VALUE,
EXTFNAPIV4_DESCRIBE_COL_IS_USED_BY_CONSUMER,
EXTFNAPIV4_DESCRIBE_COL_MINIMUM_VALUE,
EXTFNAPIV4_DESCRIBE_COL_MAXIMUM_VALUE,
EXTFNAPIV4_DESCRIBE_COL_VALUES_SUBSET_OF_INPUT,
} a_v4_extfn_describe_col_type;
EXTFNAPIV4_DESCRIBE_COL_NAME (Get)
The EXTFNAPIV4_DESCRIBE_COL_NAME attribute indicates the column name. Used in a
describe_column_get scenario.
Data Type
char[]
Description
The column name. This property is valid only for table arguments.
Usage
If a UDF gets this property, then the name of the specified column is returned.
Returns
On success, returns the length of the column name.
On failure, returns one of the generic describe_column errors, or:
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – get error returned if the query
processing phase is not greater than Initial.
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – get error returned if the
buffer length has insufficient characters or is 0 length.
• EXTFNAPIV4_DESCRIBE_NON_TABLE_PARAMETER – get error returned if the
parameter is not a TABLE parameter.
EXTFNAPIV4_DESCRIBE_COL_TYPE (Get)
The EXTFNAPIV4_DESCRIBE_COL_TYPE attribute indicates the data type of the column.
Used in a describe_column_get scenario.
Data Type
a_sql_data_type
Programming 27
Using In-Database Analytics in Applications
Description
The data type of the column. This property is valid only for table arguments.
Usage
If a UDF gets this property, then returns the data type of the specified column.
Returns
On success, the sizeof(a_sql_data_type) is returned.
On failure, returns one of the generic describe_column errors, or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – get error returned if the
describe buffer is not the size of a_sql_data_type.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – get error returned if the query
processing phase is not greater than Initial.
EXTFNAPIV4_DESCRIBE_COL_WIDTH (Get)
The EXTFNAPIV4_DESCRIBE_COL_WIDTH attribute indicates the width of the column.
Used in a describe_column_get scenario.
Data Type
a_sql_uint32
Description
The width of a column. Column width is the amount of storage, in bytes, required to store a
value of the associated data type. This property is valid only for table arguments.
Usage
If a UDF gets this property, then returns the width of the column as defined in the CREATE
PROCEDURE statement.
Returns
On success, returns the sizeof(a_sql_uint32).
On failure, returns one of the generic describe_column errors, or:
28 SAP Sybase IQ
Using In-Database Analytics in Applications
EXTFNAPIV4_DESCRIBE_COL_SCALE (Get)
The EXTFNAPIV4_DESCRIBE_COL_SCALE attribute indicates the scale of the column. Used
in a describe_column_get scenario.
Data Type
a_sql_uint32
Description
The scale of a column. For arithmetic data types, parameter scale is the number of digits to the
right of the decimal point in a number. This property is valid only for table arguments.
Usage
If the UDF gets this property, returns the scale of the column as defined in the CREATE
PROCEDURE statement. This property is valid only for arithmetic data types.
Returns
On success, returns the sizeof(a_sql_uint32) if the value was returned, or:
• EXTFNAPIV4_DESCRIBE_NOT_AVAILABLE – get error returned if the scale is
unavailable for the data type of the specified column.
On failure, returns one of the generic describe_column errors, or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – get error returned if the
describe buffer is not the size of a_sql_uint32.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – get error returned if the query
processing phase is not greater than Initial.
Programming 29
Using In-Database Analytics in Applications
• Execution phase
EXTFNAPIV4_DESCRIBE_COL_CAN_BE_NULL (Get)
The EXTFNAPIV4_DESCRIBE_COL_CAN_BE_NULL attribute indicates if the column can be
NULL. Used in a describe_column_get scenario.
Data Type
a_sql_byte
Description
True, if the column can be NULL. This property is valid only for table arguments. This
property is valid only for argument 0.
Usage
If a UDF gets this property, returns 1 if the column can be NULL, and returns 0 if otherwise.
Returns
On success, returns the sizeof(a_sql_byte) if the attribute is available, or:
• EXTFNAPIV4_DESCRIBE_NOT_AVAILABLE – returned if the attribute was not
available to get. This can happen if the column was not involved in the query.
On failure, returns one of the generic describe_column errors, or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – get error returned if the
describe buffer is not the size of a_sql_byte.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – get error returned if the specified
argument is an input table and the query processing phase is not greater than Plan Building
phase.
EXTFNAPIV4_DESCRIBE_COL_DISTINCT_VALUES (Get)
The EXTFNAPIV4_DESCRIBE_COL_DISTINCT_VALUES attribute describes the distinct
values for a column. Used in a describe_column_get scenario.
Data Type
a_v4_extfn_estimate
Description
The estimated number of distinct values for a column. This property is valid only for table
arguments.
30 SAP Sybase IQ
Using In-Database Analytics in Applications
Usage
If a UDF gets this property, it returns the estimated number of distinct values for a column.
Returns
On success, returns the sizeof(a_v4_extfn_estimate), if it returns a value, or:
• EXTFNAPIV4_DESCRIBE_NOT_AVAILABLE – returned if the attribute was not
available to get. This can happen if the column was not involved in the query.
On failure, returns one of the generic describe_column errors, or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – get error returned if the
describe buffer is not the size of a_v4_extfn_estimate.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – get error returned if the specified
argument is an input table and the query processing phase is greater than Optimization.
Example
Consider this procedure definition and code fragment in the _describe_extfn API
function:
CREATE PROCEDURE my_tpf( col_char char(10), col_table TABLE( c1 INT,
c2 INT ) )
RESULTS ( r1 INT, r2 INT, r3 INT )
EXTERNAL ‘my_tpf_proc@mylibrary’;
CREATE TABLE T( x INT, y INT, z INT );
select * from my_tpf( 'test', TABLE( select x,y from T ) )
This example shows how a TPF gets the number of distinct values for column one of the input
table. A TPF may want to get this value, if it is beneficial for choosing an appropriate
processing algorithm.
my_tpf_describe(a_v4_extfn_proc_context *cntxt)
{
if( cntxt->current_state == EXTFNAPIV4_STATE_PLAN_BUILDING ) {
a_v4_extfn_estimate num_distinct;
a_sql_int32 ret = 0;
Programming 31
Using In-Database Analytics in Applications
&num_distinct,
sizeof(a_v4_extfn_estimate) );
// default algorithm is 1
_algorithm = 1;
EXTFNAPIV4_DESCRIBE_COL_IS_UNIQUE (Get)
The EXTFNAPIV4_DESCRIBE_COL_IS_UNIQUE attribute indicates if a column is unique in
the table. Used in a describe_column_get scenario.
Data Type
a_sql_byte
Description
True, if the column is unique within the table. This property is valid only for table arguments.
Usage
If the UDF gets this property, then returns 1 if the column is unique, and 0 otherwise.
Returns
On success, returns the sizeof(a_sql_byte) or:
• EXTFNAPIV4_DESCRIBE_NOT_AVAILABLE – if the attribute was unavailable to get.
This can happen if the column was not involved in the query.
On failure, returns one of the generic describe_column errors, or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – get error returned if the
describe buffer is not the size of a_sql_byte.
32 SAP Sybase IQ
Using In-Database Analytics in Applications
EXTFNAPIV4_DESCRIBE_COL_IS_CONSTANT (Get)
The EXTFNAPIV4_DESCRIBE_COL_IS_CONSTANT attribute indicates if a column is
constant. Used in a describe_column_get scenario.
Data Type
a_sql_byte
Description
True, if the column is constant for the lifetime of the statement. This property is valid only for
input table arguments.
Usage
If a UDF gets this property, the return value is 1 if the column is constant for the lifetime of the
statement and 0 otherwise. Input table columns are constant, if the column in the select list for
the input table is a constant expression or NULL.
Returns
On success, returns the sizeof(a_sql_byte), if the value was returned, or:
• EXTFNAPIV4_DESCRIBE_NOT_AVAILABLE – the attribute is not available to get.
Returned, if the column is not involved in the query.
On failure, returns one of the generic describe_column errors, or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – get error returned, if the
describe buffer is not the size of a_sql_byte.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – get error returned, if the query
processing phase is not greater than Initial.
• EXTFNAPIV4_DESCRIBE_INVALID_PARAMETER – get error returned, if the
specified argument is not an input table.
Programming 33
Using In-Database Analytics in Applications
• Annotation phase
• Query Optimization phase
• Plan Building phase
• Execution phase
EXTFNAPIV4_DESCRIBE_COL_CONSTANT_VALUE (Get)
The EXTFNAPIV4_DESCRIBE_COL_CONSTANT_VALUE attribute indicates the constant
value of a column. Used in a describe_column_get scenario.
Data Type
an_extfn_value
Description
The value of the column, if it is constant for the statement lifetime. If
EXTFNAPIV4_DESCRIBE_COL_IS_CONSTANT for this column returns true, this value
is available. This property is valid only for table arguments.
Usage
For columns of input tables that have a constant value, the value is returned. If the value is
unavailable, then NULL is returned.
Returns
On success, returns the sizeof(a_sql_byte), if the value was returned, or:
• EXTFNAPIV4_DESCRIBE_NOT_AVAILABLE – the attribute is not available to get.
Returned, if the column is not involved in the query, or if the value is not considered
constant.
On failure, returns one of the generic describe_column errors, or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – get error returned, if the
describe buffer is not the size of a_sql_byte.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – get error returned, if the query
processing phase is not greater than Initial.
• EXTFNAPIV4_DESCRIBE_INVALID_PARAMETER – get error returned, if the
specified argument is not an input table.
34 SAP Sybase IQ
Using In-Database Analytics in Applications
EXTFNAPIV4_DESCRIBE_COL_IS_USED_BY_CONSUMER (Get)
The EXTFNAPIV4_DESCRIBE_COL_IS_USED_BY_CONSUMER attribute indicates if a
column in the result table is used by the consumer. Used in a describe_column_get
scenario.
Data Type
a_sql_byte
Description
Used either to determine whether a column in the result table is used by the consumer, or to
indicate that a column in an input is not needed. Valid for table arguments. Allows the user to
set or retrieve information about a single column, whereas the similar attribute
EXTFNAPIV4_DESCRIBE_PARM_TABLE_UNUSED_COLUMNS sets or retrieves
information about all columns in a single call.
Usage
The UDF queries this property to determine if a result table column is required by the
consumer. This can help the UDF avoid unnecessary work for unused columns.
Returns
On success, returns the sizeof(a_sql_byte) or:
• EXTFNAPIV4_DESCRIBE_NOT_AVAILABLE – if the attribute was unavailable to get.
This can happen if the column was not involved in the query.
On failure, returns one of the generic describe_column errors, or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – get error returned if the
describe buffer is not the size of a_v4_extfn_estimate.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – get error returned if the query
processing phase is not greater than Initial.
• EXTFNAPIV4_DESCRIBE_INVALID_PARAMETER – get error returned if the
argument specified is not argument 0.
Programming 35
Using In-Database Analytics in Applications
INT ) )
RESULTS ( r1 INT, r2 INT, r3 INT )
EXTERNAL ‘my_tpf_proc@mylibrary’;
When this TPF runs, it is beneficial to know if the user has selected column r1 of the result set.
If the user does not need r1, calculations for r1 may be unnecessary and we do not need to
produce it for the server.
my_tpf_describe(a_v4_extfn_proc_context *cntxt)
{
if( cntxt->current_state > EXTFNAPIV4_STATE_INITIAL ) {
a_sql_byte col_is_used = 0;
a_sql_int32 ret = 0;
EXTFNAPIV4_DESCRIBE_COL_MINIMUM_VALUE (Get)
The EXTFNAPIV4_DESCRIBE_COL_MINIMUM_VALUE attribute indicates the minimum
value for a column. Used in a describe_column_get scenario.
Data Type
an_extfn_value
Description
The minimum value for a column, if available. Valid only for argument 0 and table arguments.
Usage
If a UDF gets the EXTFNAPIV4_DESCRIBE_COL_MINIMUM_VALUE property, the minimum
value of the column data is returned in the describe_buffer. If the input table is a base table, the
minimum value is based on all of the column data in the table and is accessible only if there is
an index on the table column. If the input table is the result of another UDF, the minimum value
is the EXTFNAPIV4_DESCRIBE_COL_TYPE set by that UDF.
The data type for this property is different for different columns. The UDF can use
EXTFNAPIV4_DESCRIBE_COL_TYPE to determine the data type of the column. The UDF
36 SAP Sybase IQ
Using In-Database Analytics in Applications
Returns
On success, returns the describe_buffer_length, or:
• EXTFNAPIV4_DESCRIBE_NOT_AVAILABLE – if the attribute was unavailable to get.
Returned if the column was not involved in the query or the minimum value was
unavailable for the requested column.
On failure, returns one of the generic describe_column errors, or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – Get error returned, if the
describe buffer is not large enough to hold the minimum value.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – Get error returned if the state is not
greater than Initial.
Example
The procedure definition and code fragment in the _describe_extfn API function:
CREATE PROCEDURE my_tpf( col_char char(10), col_table TABLE( c1 INT,
c2 INT ) )
RESULTS ( r1 INT, r2 INT, r3 INT )
EXTERNAL ‘my_tpf_proc@mylibrary’;
This example illustrates how a TPF would get the minimum value for column two of the input
table, for internal optimization purposes.
my_tpf_describe(a_v4_extfn_proc_context *cntxt)
{
if( cntxt->current_state > EXTFNAPIV4_STATE_INITIAL ) {
a_sql_int32 min_value = 0;
a_sql_int32 ret = 0;
Programming 37
Using In-Database Analytics in Applications
}
}
EXTFNAPIV4_DESCRIBE_COL_MAXIMUM_VALUE (Get)
The EXTFNAPIV4_DESCRIBE_COL_MAXIMUM_VALUE attribute indicates the maximum
value for the column. Used in a describe_column_get scenario.
Data Type
an_extfn_value
Description
The maximum value for a column. This property is valid only for argument 0 and table
arguments.
Usage
If a UDF gets the EXTFNAPIV4_DESCRIBE_COL_MAXIMUM_VALUE property, then the
maximum value of the column data is returned in the describe_buffer. If the input table is a
base table, the maximum value is based on all of the column data in the table and is accessible
only if there is an index on the table column. If the input table is the result of another UDF, the
maximum value is the COL_MAXIMUM_VALUE set by that UDF.
The data type for this property is different for different columns. The UDF can use
EXTFNAPIV4_DESCRIBE_COL_TYPE to determine the data type of the column. The UDF
can also use EXTFNAPIV4_DESCRIBE_COL_WIDTH to determine the storage
requirements of the column, to provide an equivalently sized buffer to hold the value.
describe_buffer_length allows the server to determine if the buffer is valid.
If EXTFNAPIV4_DESCRIBE_COL_MAXIMUM_VALUE is unavailable,
describe_buffer is NULL.
Returns
On success, returns the describe_buffer_length or:
38 SAP Sybase IQ
Using In-Database Analytics in Applications
Example
The PROCEDURE definition and code fragment in the _describe_extfn API function:
CREATE PROCEDURE my_tpf( col_char char(10), col_table TABLE( c1 INT,
c2 INT ) )
RESULTS ( r1 INT, r2 INT, r3 INT )
EXTERNAL ‘my_tpf_proc@mylibrary’;
This example illustrates how a TPF would get the maximum value for column two of the input
table, for internal optimization purposes.
my_tpf_describe(a_v4_extfn_proc_context *cntxt)
{
if( cntxt->current_state > EXTFNAPIV4_STATE_INITIAL ) {
a_sql_int32 max_value = 0;
a_sql_int32 ret = 0;
Programming 39
Using In-Database Analytics in Applications
EXTFNAPIV4_DESCRIBE_COL_VALUES_SUBSET_OF_INPUT (Get)
The EXTFNAPIV4_DESCRIBE_COL_VALUES_SUBSET_OF_INPUT attribute sets a subset of
the values specified in an input column. Using this attribute in a describe_column_get
scenario returns an error.
Data Type
a_v4_extfn_col_subset_of_input
Description
Column values are a subset of the values specified in an input column.
Usage
This attribute can be set only.
Returns
Returns the error EXTFNAPIV4_DESCRIBE_INVALID_ATTRIBUTE.
*describe_column_set
The describe_column_set v4 API method sets UDF column-level properties on the
server.
Description
Column-level properties describe various characteristics about columns in the result set or
input tables in a TPF. For example, a UDF can tell the server that a column in its result set will
have only ten distinct values.
Declaration
a_sql_int32 (SQL_CALLBACK *describe_column_set)(
a_v4_extfn_proc_context *cntxt,
a_sql_uint32 arg_num,
a_sql_uint32 column_num,
a_v4_extfn_describe_udf_type describe_type,
const void *describe_buffer,
size_t describe_buffer_len );
Parameters
Parameter Description
cntxt The procedure context object for this UDF.
40 SAP Sybase IQ
Using In-Database Analytics in Applications
Parameter Description
arg_num The ordinal of the TABLE parameter (0 is the
result table, 1 for first input argument).
Returns
On success, returns the number of bytes written to the describe_buffer. If an error occurs, or
no property is retrieved, this function returns one of the generic describe_column errors.
EXTFNAPIV4_DESCRIBE_COL_NAME (Set)
The EXTFNAPIV4_DESCRIBE_COL_NAME attribute indicates a column name. Used in a
describe_column_set scenario.
Data Type
char[]
Programming 41
Using In-Database Analytics in Applications
Description
The column name. This property is valid only for table arguments.
Usage
For argument 0, if the UDF sets this property, the server compares the value with the name of
the column supplied in the CREATE PROCEDURE statement. The comparison ensures that the
CREATE PROCEDURE statement has the same column name as expected by the UDF.
Returns
On success, returns the length of the column name.
On failure, returns one of the generic describe_column errors, or:
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – set error returned if the state is not
Annotation.
• EXTFNAPIV4_DESCRIBE_NON_TABLE_PARAMETER – set error returned if the
parameter is not a TABLE parameter.
• EXTFNAPIV4_DESCRIBE_ INVALID_ATTRIBUTE_VALUE – set error returned if
the length of input column name exceeds 128 characters or if the input column name and
column name stored in the catalog do not match.
Example
short desc_rc = 0;
char name[7] = ‘column1’;
// Verify that the procedure was created with the second column
of the result table as an int
if( ctx->current_state == EXTFNAPIV4_STATE_ANNOTATION ) {
desc_rc = ctx->describe_column_set( ctx, 0, 2,
EXTFNAPIV4_DESCRIBE_COL_NAME,
name,
sizeof(name) );
if( desc_rc < 0 ) {
// handle the error.
}
}
EXTFNAPIV4_DESCRIBE_COL_TYPE (Set)
The EXTFNAPIV4_DESCRIBE_COL_TYPE attribute indicates the data type of the column.
Used in a describe_column_set scenario.
Data Type
a_sql_data_type
42 SAP Sybase IQ
Using In-Database Analytics in Applications
Description
The data type of the column. This property is valid only for table arguments.
Usage
For argument zero, if the UDF sets this property, then the server compares the value with the
data type of the column supplied in the CREATE PROCEDURE statement. This allows the
UDF to ensure the CREATE PROCEDURE statement has the same data type as expected by the
UDF.
Returns
On success, returns the a_sql_data_type.
On failure, returns one of the generic describe_column errors, or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – Set error returned if the
describe buffer is not the size of a_sql_data_type.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – Set error returned if the state is not
Annotation.
• EXTFNAPIV4_DESCRIBE_ INVALID_ATTRIBUTE_VALUE – Set error returned if
the input data type and the data type stored in the catalog do not match,.
Example
short desc_rc = 0;
a_sql_data_type type = DT_INT;
// Verify that the procedure was created with the second column of
the result table as an int
if( ctx->current_state == EXTFNAPIV4_STATE_ANNOTATION ) {
desc_rc = ctx->describe_column_set( ctx, 0, 2,
EXTFNAPIV4_DESCRIBE_COL_TYPE,
&type,
sizeof(a_sql_data_type) );
if( desc_rc < 0 ) {
// handle the error.
}
}
EXTFNAPIV4_DESCRIBE_COL_WIDTH (Set)
The EXTFNAPIV4_DESCRIBE_COL_WIDTH attribute indicates the width of the column.
Used in a describe_column_set scenario.
Data Type
a_sql_uint32
Programming 43
Using In-Database Analytics in Applications
Description
The width of a column. Column width is the amount of storage, in bytes, required to store a
value of the associated data type. This property is valid only for table arguments.
Usage
If the UDF sets this property, the server compares the value with the width of the column
supplied in the CREATE PROCEDURE statement. This allows the UDF to ensure the CREATE
PROCEDURE statement has the same column width as expected by the UDF.
Returns
On success, returns the sizeof(a_sql_uint32).
On failure, returns one of the generic describe_column errors, or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – set error returned if the
describe buffer is not the size of a_sql_uint32.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – set error returned if the query
processing state is not Annotation.
• EXTFNAPIV4_DESCRIBE_INVALID_ATTRIBUTE_VALUE – set error returned if
the input width and width stored in the catalog do not match.
EXTFNAPIV4_DESCRIBE_COL_SCALE (Set)
The EXTFNAPIV4_DESCRIBE_COL_SCALE attribute indicates the scale of the column. Used
in a describe_column_set scenario.
Data Type
a_sql_uint32
Description
The scale of a column. For arithmetic data types, parameter scale is the number of digits to the
right of the decimal point in a number. This property is valid only for table arguments.
Usage
If the UDF sets this property, the server compares the value with the scale of the column
supplied in the CREATE PROCEDURE statement. This allows the UDF to ensure the CREATE
PROCEDURE statement has the same column width as expected by the UDF. This property is
valid only for arithmetic data types.
Returns
On success, returns the sizeof(a_sql_uint32), or:
44 SAP Sybase IQ
Using In-Database Analytics in Applications
Example
short desc_rc = 0;
a_sql_uint32 scale = 0;
EXTFNAPIV4_DESCRIBE_COL_CAN_BE_NULL (Set)
The EXTFNAPIV4_DESCRIBE_COL_CAN_BE_NULL attribute indicates if the column can be
null. Used in a describe_column_set scenario.
Data Type
a_sql_byte
Description
True, if the column can be NULL. This property is valid only for table arguments. This
property is valid only for argument 0.
Usage
The UDF can set this property for a result table column if that column can be NULL. If the
UDF does not explicitly set this property, it is assumed that the column can be NULL. The
server can use this information during the Optimization state.
Programming 45
Using In-Database Analytics in Applications
Returns
On success, returns the sizeof(a_sql_byte) if the attribute was set or:
• EXTFNAPIV4_DESCRIBE_NOT_AVAILABLE – returned if the attribute was
unavailable to set, which may happen if the column was uninvolved in the query.
On failure, returns one of the generic describe_column errors, or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – set error returned if the
describe buffer is not the size of a_sql_byte.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – set error returned if the state is not
equal to OPTIMIZATION.
• EXTFNAPIV4_DESCRIBE_INVALID_ATTRIBUTE_VALUE – set error returned if
the UDF attempts to set this attribute to a value other than 0 or 1.
EXTFNAPIV4_DESCRIBE_COL_DISTINCT_VALUES (Set)
The EXTFNAPIV4_DESCRIBE_COL_DISTINCT_VALUES attribute describes the distinct
values for a column. Used in a describe_column_set scenario.
Data Type
a_v4_extfn_estimate
Description
The estimated number of distinct values for a column. This property is valid only for table
arguments.
Usage
The UDF can set this property if it knows how many distinct values a column can have in its
result table. The server uses this information during the Optimization state.
Returns
On success, returns the sizeof(a_v4_extfn_estimate), if it sets the value, or:
• EXTFNAPIV4_DESCRIBE_NOT_AVAILABLE – returned if the attribute was
unavailable to set. This can happen if the column was not involved in the query.
On failure, returns:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – set error returned if the
describe buffer is not the size of a_v4_extfn_estimate.
46 SAP Sybase IQ
Using In-Database Analytics in Applications
EXTFNAPIV4_DESCRIBE_COL_IS_UNIQUE (Set)
The EXTFNAPIV4_DESCRIBE_COL_IS_UNIQUE attribute indicates if the column is unique
in the table. Used in a describe_column_set scenario.
Data Type
a_sql_byte
Description
True, if the column is unique within the table. This property is valid only for table arguments.
Usage
The UDF can set this property if it knows the result table column value is unique. The server
uses this information during the Optimization state. The UDF can set this property only for
argument 0.
Returns
On success, returns the sizeof(a_sql_byte) or:
• EXTFNAPIV4_DESCRIBE_NOT_AVAILABLE – if the attribute was not available to
set. This can happen if the column was not involved in the query.
On failure, returns one of the generic describe_column errors, or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – set error returned if the
describe buffer is not the size of a_sql_byte.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – set error returned if the query
processing state is not Optimization.
• EXTFNAPIV4_DESCRIBE_INVALID_PARAMETER – set error returned if the
arg_num is not zero.
• EXTFNAPIV4_DESCRIBE_INVALID_ATTRIBUTE_VALUE – set error returned if
the UDF attempts to set this attribute to a value other than 0 or 1.
Programming 47
Using In-Database Analytics in Applications
EXTFNAPIV4_DESCRIBE_COL_IS_CONSTANT (Set)
The EXTFNAPIV4_DESCRIBE_COL_IS_CONSTANT attribute indicates if the column is
constant. Used in a describe_column_set scenario.
Data Type
a_sql_byte
Description
True, if the column is constant for the lifetime of the statement. This property is valid only for
input table arguments.
Usage
This is a read only property. All attempts to set it return
EXTFNAPIV4_DESCRIBE_INVALID_ATTRIBUTE.
Returns
• EXTFNAPIV4_DESCRIBE_INVALID ATTRIBUTE – this is a read-only property; all
attempts to set return this error.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – set error returned, if the state is not
Optimization.
• EXTFNAPIV4_DESCRIBE_INVALID_PARAMETER – set error returned, if the
arg_num is not zero.
• EXTFNAPIV4_DESCRIBE_INVALID_ATTRIBUTE_VALUE – set error returned, if
the UDF attempts to set this attribute to a value other than 0 or 1.
EXTFNAPIV4_DESCRIBE_COL_CONSTANT_VALUE (Set)
The EXTFNAPIV4_DESCRIBE_COL_CONSTANT_VALUE attribute indicates the constant
value of the column. Used in a describe_column_set scenario.
Data Type
an_extfn_value
Description
The value of the column, if it is constant for the statement lifetime. If
EXTFNAPIV4_DESCRIBE_COL_IS_CONSTANT for this column returns true, this value
is available. This property is valid only for table arguments.
Usage
This property is read-only.
48 SAP Sybase IQ
Using In-Database Analytics in Applications
Returns
• EXTFNAPIV4_DESCRIBE_INVALID_ATTRIBUTE – this is a read-only property; all
attempts to set return this error.
EXTFNAPIV4_DESCRIBE_COL_IS_USED_BY_CONSUMER (Set)
The EXTFNAPIV4_DESCRIBE_COL_IS_USED_BY_CONSUMER attribute indicates if the
column in the result table is used by the consumer. Used in a describe_column_set
scenario.
Data Type
a_sql_byte
Description
Used either to determine whether a column in the result table is used by the consumer, or to
indicate that a column in an input is not needed. Valid for table arguments. Allows the user to
set or retrieve information about a single column, whereas the similar attribute
EXTFNAPIV4_DESCRIBE_PARM_TABLE_UNUSED_COLUMNS sets or retrieves
information about all columns in a single call.
Usage
The UDF sets EXTFNAPIV4_DESCRIBE_COL_IS_USED_BY_CONSUMER on columns in an
input table to inform the producer that it does not need values for the column.
Returns
On success, returns the sizeof(a_sql_byte) or:
• EXTFNAPIV4_DESCRIBE_NOT_AVAILABLE – if the attribute was not available to
set. This can happen if the column was not involved in the query.
On failure, returns one of the generic describe_column errors, or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – set error returned if the
describe buffer is not the size of a_v4_extfn_estimate.
• EXTFNAPIV4_DESCRIBE_INVALID_PARAMETER – set error returned if the
argument specified is argument 0.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – set error returned if the state is not
equal to Optimization.
• EXTFNAPIV4_DESCRIBE_INVALID_ATTRIBUTE_VALUE – set error returned if
the value the UDF is setting is not 0 or 1.
Programming 49
Using In-Database Analytics in Applications
When this TPF runs, it is beneficial for the server to know if column y is used by this TPF. If the
TPF does not need y, the server can use this knowledge for optimization and does not send this
column information to the TPF.
my_tpf_describe(a_v4_extfn_proc_context *cntxt)
{
if( cntxt->current_state == EXTFNAPIV4_STATE_OPTIMIZATION ) {
a_sql_byte col_is_used = 0;
a_sql_int32 ret = 0;
}
}
EXTFNAPIV4_DESCRIBE_COL_MINIMUM_VALUE (Set)
The EXTFNAPIV4_DESCRIBE_COL_MINIMUM_VALUE attribute indicates the minimum
value for the column. Used in a describe_column_set scenario.
Data Type
an_extfn_value
Description
The minimum value a column can have, if available. Only valid for argument 0.
50 SAP Sybase IQ
Using In-Database Analytics in Applications
Usage
The UDF can set EXTFNAPIV4_DESCRIBE_COL_MINIMUM_VALUE, if it knows what
the minimum data value of the column is. The server can use this information during
optimization.
The UDF can use EXTFNAPIV4_DESCRIBE_COL_TYPE to determine the data type of the
column, and EXTFNAPIV4_DESCRIBE_COL_WIDTH to determine the storage
requirements of the column, to provide an equivalently sized buffer to hold the value to set.
Returns
On success, returns the describe_buffer_length, or:
• EXTFNAPIV4_DESCRIBE_NOT_AVAILABLE – if the attribute cannot be set.
Returned if the column was not involved in the query or the minimum value was not
available for the requested column.
On failure, returns one of the generic describe_column errors, or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – set error returned, if the
describe buffer is not large enough to hold the minimum value.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – set error returned, if the state is not
equal to Optimization.
• EXTFNAPIV4_DESCRIBE_INVALID_PARAMETER – set error returned, if the
arg_num is not 0.
Example
The PROCEDURE definition and UDF code fragment that implements the
_describe_extfn callback API function:
CREATE PROCEDURE my_tpf( col_char char(10), col_table TABLE( c1 INT,
c2 INT ) )
RESULTS ( r1 INT, r2 INT, r3 INT )
EXTERNAL ‘my_tpf_proc@mylibrary’;
This example shows a TPF where it is useful to the server (or to another TPF that takes the
result of this TPF as input) to know the minimum value of result set column one. In this
instance, the minimum output value of column one is 27.
my_tpf_describe(a_v4_extfn_proc_context *cntxt)
{
Programming 51
Using In-Database Analytics in Applications
// Tell the server what the minimum value of the first column
// of our result set will be.
EXTFNAPIV4_DESCRIBE_COL_MAXIMUM_VALUE (Set)
The EXTFNAPIV4_DESCRIBE_COL_MAXIMUM_VALUE attribute indicates the maximum
value for the column. Used in a describe_column_set scenario.
Data Type
an_extfn_value
Description
The maximum value for a column. This property is valid only for argument 0 and table
arguments.
Usage
The UDF can set EXTFNAPIV4_DESCRIBE_COL_MAXIMUM_VALUE, if it knows what
the maximum data value of the column is. The server can use this information during
optimization.
The UDF can use EXTFNAPIV4_DESCRIBE_COL_TYPE to determine the data type of the
column, and EXTFNAPIV4_DESCRIBE_COL_WIDTH to determine the storage
requirements of the column, to provide an equivalently sized buffer to hold the value to set.
describe_buffer_length is the sizeof() this buffer.
Returns
On success, returns the describe_buffer_length, if the value was set, or:
• EXTFNAPIV4_DESCRIBE_NOT_AVAILABLE – if the attribute could not be set.
Returned if the column was not involved in the query or the maximum value was not
available for the requested column.
On failure, returns one of the generic describe_column errors, or:
52 SAP Sybase IQ
Using In-Database Analytics in Applications
Example
The PROCEDURE definition and and UDF code fragment that implements the
_describe_extfn callback API function:
CREATE PROCEDURE my_tpf( col_char char(10), col_table TABLE( c1 INT,
c2 INT ) )
RESULTS ( r1 INT, r2 INT, r3 INT )
EXTERNAL ‘my_tpf_proc@mylibrary’;
This example shows a TPF where it is useful to the server (or to another TPF that takes the
result of this TPF as input) to know the maximum value of result set column one. In this
instance, the maximum output value of column one is 500000.
my_tpf_describe(a_v4_extfn_proc_context *cntxt)
{
if( cntxt->current_state == EXTFNAPIV4_STATE_OPTIMIZATION ) {
a_sql_int32 max_value = 500000;
a_sql_int32 ret = 0;
// Tell the server what the maximum value of the first column
// of our result set will be.
}
}
Programming 53
Using In-Database Analytics in Applications
EXTFNAPIV4_DESCRIBE_COL_VALUES_SUBSET_OF_INPUT (Set)
The EXTFNAPIV4_DESCRIBE_COL_VALUES_SUBSET_OF_INPUT attribute sets a subset of
the values specified in an input column. Used in a describe_column_set scenario.
Data Type
a_v4_extfn_col_subset_of_input
Description
Column values are a subset of the values specified in an input column.
Usage
Setting this describe attribute informs the query optimizer that the indicated column values are
a subset of those values specified in an input column. For example, consider a filter TPF that
consumes a table and filters out rows based on a function. In such a case, the return table is a
subset of the input table. Setting
EXTFNAPIV4_DESCRIBE_COL_VALUES_SUBSET_OF_INPUT for the filter TPF optimizes
the query.
Returns
On success, returns the sizeof(a_v4_extfn_col_subset_of_input).
On failure, returns one of the generic describe_column errors, or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – set error returned if the
buffer length is less than sizeof (a_v4_extfn_col_subset_of_input).
• EXTFNAPIV4_DESCRIBE_INVALID_ATTRIBUTE_VALUE – set error returned if
the column index of the source table is out of range.
• EXTFNAPIV4_DESCRIBE_NOT_AVAILABLE – set error returned if the column
subset_of_input is set on is not aplicable (for example, if the column is not in the
select list).
• EXTFNAPIV4_DESCRIBE_INVAILD_STATE – set error returned if the query
processing state is not Optimization.
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – set error returned if the
buffer length is zero.
• EXTFNAPIV4_DESCRIBE_INVALID_PARAMETER – set error returned if called on a
parameter other than the return table.
Example
a_v4_extfn_col_subset_of_input colMap;
54 SAP Sybase IQ
Using In-Database Analytics in Applications
colMap.source_table_parameter_arg_num = 4;
colMap.source_column_number = i;
*describe_parameter_get
The describe_parameter_get v4 API method gets UDF parameter properties from
the server.
Declaration
a_sql_int32 (SQL_CALLBACK *describe_parameter_get)(
a_v4_extfn_proc_context *cntxt,
a_sql_uint32 arg_num,
a_v4_extfn_describe_udf_type describe_type,
const void *describe_buffer,
size_t describe_buffer_len );
Parameters
Parameter Description
cntxt The procedure context object.
Returns
On success, returns 0 or the number of bytes written to the describe_buffer. A value of 0
indicates that the server was unable to get the attribute, but no error condition occurred. If an
error occurred, or no property was retrieved, this function returns one of the generic
describe_parameter errors.
Programming 55
Using In-Database Analytics in Applications
EXTFNAPIV4_DESCRIBE_PARM_TYPE,
EXTFNAPIV4_DESCRIBE_PARM_WIDTH,
EXTFNAPIV4_DESCRIBE_PARM_SCALE,
EXTFNAPIV4_DESCRIBE_PARM_CAN_BE_NULL,
EXTFNAPIV4_DESCRIBE_PARM_DISTINCT_VALUES,
EXTFNAPIV4_DESCRIBE_PARM_IS_CONSTANT,
EXTFNAPIV4_DESCRIBE_PARM_CONSTANT_VALUE,
EXTFNAPIV4_DESCRIBE_PARM_TABLE_NUM_COLUMNS,
EXTFNAPIV4_DESCRIBE_PARM_TABLE_NUM_ROWS,
EXTFNAPIV4_DESCRIBE_PARM_TABLE_ORDERBY,
EXTFNAPIV4_DESCRIBE_PARM_TABLE_PARTITIONBY,
EXTFNAPIV4_DESCRIBE_PARM_TABLE_REQUEST_REWIND,
EXTFNAPIV4_DESCRIBE_PARM_TABLE_HAS_REWIND,
EXTFNAPIV4_DESCRIBE_PARM_TABLE_UNUSED_COLUMNS,
} a_v4_extfn_describe_parm_type;
Data Type
char[]
Description
The name of a parameter to a UDF.
Usage
Gets the parameter name as defined in the CREATE PROCEDURE statement. Invalid for
parameter 0.
Returns
On success, returns the length of the parameter name.
On failure, returns one of the generic describe_parameter errors or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – get error returned if the
describe_buffer is not large enough to hold the name.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – get error returned if the query
processing phase is not greater than Initial.
• EXTFNAPIV4_DESCRIBE_INVALID_PARAMETER – get error returned if the
parameter is the result table.
56 SAP Sybase IQ
Using In-Database Analytics in Applications
Data Type
a_sql_data_type
Description
The data type of a parameter to a UDF.
Usage
Gets the data type of the parameter as defined in the CREATE PROCEDURE statement.
Returns
On success, returns sizeof(a_sql_data_type).
On failure, returns one of the generic describe_parameter errors or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – get error returned if the
describe_buffer is not the sizeof(a_sql_data_type).
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – get error returned if the query
processing phase is not greater than Initial.
Data Type
a_sql_uint32
Programming 57
Using In-Database Analytics in Applications
Description
The width of a parameter to a UDF. EXTFNAPIV4_DESCRIBE_PARM_WIDTH applies
only to scalar parameters. Parameter width is the amount of storage, in bytes, required to store
a parameter of the associated data type.
• Fixed length data types – the bytes required to store the data.
• Variable length data types – the maximum length.
• LOB data types – the amount of storage required to store a handle to the data.
• TIME data types – the amount of storage required to store the encoded time.
Usage
Gets the width of the parameter as defined in the CREATE PROCEDURE statement.
Returns
On success, returns the sizeof(a_sql_uint32).
On failure, returns one of the generic describe_parameter errors or:
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – get error returned if the query
processing phase is not greater than Initial.
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – get error returned if the
describe_buffer is not the size of a_sql_uint32.
• EXTFNAPIV4_DESCRIBE_INVALID_PARAMETER – get error returned if the
specified parameter is a TABLE parameter. This includes parameter 0, or parameter n
where n is an input table.
Example
Sample procedure definition:
CREATE PROCEDURE my_udf(IN p1 INT, IN p2 char(100))
RESULT (x INT)
EXTERNAL NAME ‘my_udf@myudflib’;
58 SAP Sybase IQ
Using In-Database Analytics in Applications
a_sql_int32 ret = 0;
}
}
Data Type
a_sql_uint32
Description
The scale of a parameter to a UDF. For arithmetic data types, parameter scale is the number of
digits to the right of the decimal point in a number.
This attribute is not valid for:
• non-arithmetic data types
• TABLE parameters
Usage
Gets the scale of the parameter as defined in the CREATE PROCEDURE statement.
Programming 59
Using In-Database Analytics in Applications
Returns
On success, returns the size of (a_sql_uint32).
On failure, returns one of the generic describe_parameter errors or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – get error returned if the
describe_buffer is not the size of a_sql_uint32.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – get error returned if the query
processing phase is not greater than Initial.
• EXTFNAPIV4_DESCRIBE_INVALID_PARAMETER – get error returned if the
specified parameter is a TABLE parameter. This includes parameter 0, or parameter n
where n is an input table.
Example
Sample _describe_extfn API function code fragment that gets the scale of parameter
1:
if( cntxt->current_state > EXTFNAPIV4_STATE_ANNOTATION ) {
a_sql_uint32 scale = 0;
a_sql_int32 ret = 0;
Data Type
a_sql_byte
60 SAP Sybase IQ
Using In-Database Analytics in Applications
Description
True, if the value of a parameter can be NULL at the time of execution. For a TABLE
parameter or parameter 0, the value is false.
Usage
Gets whether or not the specified parameter can be null during query execution.
Returns
On success, returns the sizeof(a_sql_byte).
On failure, returns one of the generic describe_parameter errors or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – Get error returned if the
describe_buffer is not the size of a_sql_byte.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – Get error returned if the query
processing phase is not greater than Plan Building.
Procedure Definition
Sample procedure definition used by the example queries in this topic:
CREATE PROCEDURE my_udf(IN p INT)
RESULT (x INT)
EXTERNAL NAME ‘my_udf@myudflib’;
Programming 61
Using In-Database Analytics in Applications
Data Type
a_v4_extfn_estimate
62 SAP Sybase IQ
Using In-Database Analytics in Applications
Description
Returns the estimated number of distinct values across all invocations. valid only for scalar
parameters.
Usage
If this information is available, the UDF returns the estimated number of distinct values with
100% confidence. If the information is not available, the UDF returns an estimate of 0 with 0%
confidence.
Returns
On success, returns the sizeof(a_v4_extfn_estimate).
On failure, returns one of the generic describe_parameter errors or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – get error returned if the
describe_buffer is not the size of a_v4_extfn_estimate.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – get error returned if the query
processing phase is not greater than Initial.
• EXTFNAPIV4_DESCRIBE_INVALID_PARAMETER – get error returned if the
parameter is a TABLE parameter.
Example
Sample _describe_extfn API function code fragment:
if( ctx->current_state >= EXTFNAPIV4_STATE_ANNOTATION ) {
desc_est.value = 0.0;
desc_est.confidence = 0.0;
Programming 63
Using In-Database Analytics in Applications
Data Type
a_sql_byte
Description
True, if the parameter is a constant for the statement. Valid only for scalar parameters.
Usage
Returns 0 if the value of the specified parameter is not a constant; returns 1 if the value of the
specified parameter is a constant.
Returns
On success, returns the sizeof(a_sql_byte).
On failure, returns one of the generic describe_parameter errors or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – get error returned if the
describe_buffer is not the size of a_sql_byte.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – get error returned if the query
processing phase is not greater than Initial.
• EXTFNAPIV4_DESCRIBE_INVALID_PARAMETER – get error returned if the
parameter is a TABLE parameter.
Example
Sample _describe_extfn API function code fragment:
if( ctx->current_state >= EXTFNAPIV4_STATE_ANNOTATION ) {
desc_rc = ctx->describe_parameter_get( ctx,
1,
EXTFNAPIV4_DESCRIBE_PARM_IS_CONSTANT,
&desc_byte, sizeof( a_sql_byte ) );
}
64 SAP Sybase IQ
Using In-Database Analytics in Applications
Data Type
an_extfn_value
Description
The value of the parameter if it is known at describe time. Valid only for scalar parameters.
Usage
Returns the value of the parameters.
Returns
On success, returns the sizeof(an_extfn_value) if the value is available, or:
• EXTFNAPIV4_DESCRIBE_NOT_AVILABLE – Value returned if the value is not
constant.
On failure, returns one of the generic describe_parameter errors or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – get error returned if the
describe_buffer is not the size of an_extfn_value.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – get error returned if the phase is not
greater than Initial.
• EXTFNAPIV4_DESCRIBE_INVALID_PARAMETER – get error returned if the
parameter is a TABLE parameter.
Example
Sample _describe_extfn API function code fragment:
if( ctx->current_state >= EXTFNAPIV4_STATE_ANNOTATION ) {
a_sql_int32 desc_rc;
desc_rc = ctx->describe_parameter_get( ctx,
1,
EXTFNAPIV4_DESCRIBE_PARM_CONSTANT_VALUE,
&arg,
sizeof( an_extfn_value ) );
}
Programming 65
Using In-Database Analytics in Applications
Data Type
a_sql_uint32
Description
The number of columns in the table. Only valid for argument 0 and table arguments.
Usage
Returns the number of columns in the specified table argument. Argument 0 returns the
number of columns in the result table.
Returns
On success, returns the sizeof(a_sql_uint32).
On failure, returns one of the generic describe_parameter errors or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – get error returned if the
describe_buffer is not the size of size of a_sql_uint32.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – get error returned if the query
processing phase is not greater than Initial.
• EXTFNAPIV4_DESCRIBE_NON_TABLE_PARAMETER – get error returned if the
parameter is not a TABLE parameter.
Data Type
a_v4_extfn_estimate
Description
The estimated number of rows in the table. Only valid for argument 0 and table arguments.
66 SAP Sybase IQ
Using In-Database Analytics in Applications
Usage
Returns the estimated number of rows in the specified table argument or result set with a
confidence of 100%.
Returns
On success, returns the size of a_v4_extfn_estimate.
On failure, returns one of the generic describe_parameter errors or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – get error returned if the
describe_buffer is not the size of a_v4_extfn_estimate.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – get error returned if the query
processing phase is not greater than Initial.
• EXTFNAPIV4_DESCRIBE_NON_TABLE_PARAMETER – get error returned if the
parameter is not a TABLE parameter.
Data Type
a_v4_extfn_orderby_list
Description
The order of rows in the table. This property is only valid for argument 0 and table arguments.
Usage
This attribute allows the UDF code to:
• Determine if the input TABLE parameter has been ordered
• Declare that the result set is ordered
If the parameter number is 0, then the attribute refers to the outbound result set. If the
parameter is > 0 and the parameter type is a table then the attribute refers to the input TABLE
parameter.
The order is specified by the a_v4_extfn_orderby_list, which is a structure
supporting a list of column ordinals and their associated ascending or descending property. If
Programming 67
Using In-Database Analytics in Applications
the UDF sets the order by property for the outbound result set, the server is then able to
perform order by optimizations. For example, if the UDF produced ascending order on the
first result set column, the server will eliminate a redundant order by request on the same
column.
If the UDF does not set the orderby property on the outbound result set, the server assumes the
data is not ordered.
If the UDF sets the orderby property on the input TABLE parameter, the server guarantees data
ordering for the input data. In this scenario, the UDF describes to the server that the input data
must be ordered. If the server detects a runtime conflict it raises a SQL exception. For
example, when the UDF describes that the first column of the input TABLE parameter must
have ascending order and the SQL statement contains a descending clause, the server raises a
SQL exception.
In the event that the SQL did not contain an ordering clause, the server automatically adds the
ordering to ensure that input TABLE parameter is ordered as required.
Returns
If successful, returns the number of bytes copied from a_v4_extfn_orderby_list.
EXTFNAPIV4_DESCRIBE_PARM_TABLE_PARTITIONBY (Get)
The EXTFNAPIV4_DESCRIBE_PARM_TABLE_PARTITIONBY attribute indicates that
the UDF requires partitioning. Used in a describe_parameter_get scenario.
Data Type
a_v4_extfn_column_list
Description
UDF developers use EXTFNAPIV4_DESCRIBE_PARM_TABLE_PARTITIONBY to
programmatically declare that the UDF requires partitioning before invocation can proceed.
Usage
The UDF can inquire to the partition to enforce it, or to dynamically adapt the partitioning. It is
the UDF's responsibility to allocate the a_v4_extfn_column_list, taking into consideration the
total number of columns in the input table, and sending that data to the server.
Returns
On success, returns the size of a_v4_extfn_column_list. This value is equal to:
68 SAP Sybase IQ
Using In-Database Analytics in Applications
sizeof(a_v4_extfn_column_list) + sizeof(a_sql_uint32) *
number_of_partition_columns
Example
void UDF_CALLBACK my_tpf_proc_describe( a_v4_extfn_proc_context
*ctx )
{
if( ctx->current_state == EXTFNAPIV4_STATE_OPTIMIZATION ) {
a_sql_uint32 col_count = 0;
a_sql_uint32 buffer_size = 0;
a_v4_extfn_column_list *clist = NULL;
clist->number_of_columns = 0;
clist->column_indexes[0] = 0;
clist->column_indexes[1] = 0;
clist->column_indexes[2] = 0;
Programming 69
Using In-Database Analytics in Applications
Data Type
a_sql_byte
Description
Indicates that the consumer wants to rewind an input table. Valid only for table input
arguments. By default, this property is false.
Usage
The UDF queries this property to retrieve the true/false value.
Returns
On success, returns sizeof(a_sql_byte).
On failure, returns one of the generic describe_parameter errors, or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – get error returned if the
describe_buffer is not the size of a_sql_byte.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – get error returned if the phase is not
Optimization or Plan Building.
• EXTFNAPIV4_DESCRIBE_INVALID_PARAMETER – get error returned if the UDF
attempts to get this attribute on parameter 0.
• EXTFNAPIV4_DESCRIBE_NON_TABLE_PARAMETER – get error returned if the
UDF attempts to get this attribute on a parameter that is not a table.
Data Type
a_sql_byte
Description
Indicates whether a producer can support rewind. Valid only for table arguments.
70 SAP Sybase IQ
Using In-Database Analytics in Applications
You must also provide an implementation of the rewind table callback (_rewind_extfn() ) if
you plan on setting DESCRIBE_PARM_TABLE_HAS_REWIND to true. The server will
fail to execute the UDF if the callback method is not provided.
Usage
The UDF asks if a table input argument supports rewind. As a prerequisite, the UDF must
request rewind using DESCRIBE_PARM_TABLE_REQUEST_REWIND before you can use
this property.
Returns
On success, returns sizeof(a_sql_byte).
On failure, returns one of the generic describe_parameter errors, or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – get error returned if the
describe_buffer is not the size of a_sql_byte.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – get error error returned if the query
processing phase is not greater than Annotation.
• EXTFNAPIV4_DESCRIBE_NON_TABLE_PARAMETER – get error returned if the
UDF attempts to get this attribute on a parameter that is not a table.
• EXTFNAPIV4_DESCRIBE_INVALID_PARAMETER – get error returned if the UDF
attempts to get this attribute on the result table.
Data Type
a_v4_extfn_column_list
Description
The list of output table columns that are not going to be consumed by the server or the UDF.
For the output TABLE parameter, the UDF normally produces the data for all the columns, and
the server consumes all the columns. The same holds true for the input TABLE parameter
where the server normally produces the data for all the columns, and the UDF consumes all the
columns.
However, in some cases the server, or the UDF, may not consume all the columns. The best
practice in such a case is for the UDF to perform a GET for the output table on the describe
Programming 71
Using In-Database Analytics in Applications
Usage
The UDF asks the server if all the columns of the output table are going to be used. The UDF
must allocate a a_v4_extfn_column_list that includes all the columns of the output
table, and then must pass it to the server. The server then marks all the unprojected column
ordinals as 1. The list returned by the server can be used while producing the data.
Returns
On success, returns the size of the column list: sizeof(a_v4_extfn_column_list)
+ sizeof(a_sql_uint32) * number result columns.
On failure, returns one of the generic describe_parameter errors or:
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – get error returned if the query
processing phase is not greater than Plan Building.
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – get error returned if the
describe_buffer is not large enough to hold the returned list.
• EXTFNAPIV4_DESCRIBE_INVALID_PARAMETER – get error returned if the UDF
attempts to get this attribute on an input table.
• EXTFNAPIV4_DESCRIBE_NON_TABLE_PARAMETER – get error returned if the
UDF attempts to get this attribute on a parameter that is not a table.
*describe_parameter_set
The describe_parameter_set v4 API method sets properties about a single parameter
to the UDF.
Declaration
a_sql_int32 (SQL_CALLBACK *describe_parameter_set)(
a_v4_extfn_proc_context *cntxt,
a_sql_uint32 arg_num,
a_v4_extfn_describe_udf_type describe_type,
const void *describe_buffer,
size_t describe_buffer_len );
72 SAP Sybase IQ
Using In-Database Analytics in Applications
Parameters
Parameter Description
cntxt The procedure context object.
Returns
On success, returns 0 or the number of bytes written to the describe_buffer. A value of 0
indicates that the server was unable to set the attribute, but no error condition occurred. If an
error occurred, or no property was retrieved, this function returns one of the generic
describe_parameter errors.
EXTFNAPIV4_DESCRIBE_PARM_TABLE_NUM_COLUMNS,
EXTFNAPIV4_DESCRIBE_PARM_TABLE_NUM_ROWS,
EXTFNAPIV4_DESCRIBE_PARM_TABLE_ORDERBY,
EXTFNAPIV4_DESCRIBE_PARM_TABLE_PARTITIONBY,
EXTFNAPIV4_DESCRIBE_PARM_TABLE_REQUEST_REWIND,
EXTFNAPIV4_DESCRIBE_PARM_TABLE_HAS_REWIND,
EXTFNAPIV4_DESCRIBE_PARM_TABLE_UNUSED_COLUMNS,
} a_v4_extfn_describe_parm_type;
Programming 73
Using In-Database Analytics in Applications
Data Type
char[]
Description
The name of a parameter to a UDF.
Usage
If the UDF sets this property, the server compares the value with the name of the parameter
supplied in the CREATE PROCEDURE statement. If the two values do not match, the server
returns an error. This allows the UDF to ensure the CREATE PROCEDURE statement has the
same parameter names as the UDF is expecting.
Returns
On success, returns the length of the parameter name.
On failure, returns one of the generic describe_parameter errors or:
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – set error returned if the state is not
equal to Annotation.
• EXTFNAPIV4_DESCRIBE_INVALID_PARAMETER – set error returned if the
parameter is the result table.
• EXTFNAPI4_DESCRIBE_INVALID_ATTRIBUTE_VALUE – set error returned if the
UDF tries to reset the name.
Data Type
a_sql_data_type
Description
The data type of a parameter to a UDF.
74 SAP Sybase IQ
Using In-Database Analytics in Applications
Usage
When the UDF sets this property, the server compares the value to the parameter type supplied
in the CREATE PROCEDURE statement. If the two values do not match, the server returns an
error. This check ensures that the CREATE PROCEDURE statement has the same parameter
data types that the UDF expects.
Returns
On success, returns sizeof(a_sql_data_type).
On failure, returns one of the generic describe_parameter errors or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – set error returned if the
describe_buffer is not the sizeof(a_sql_data_type).
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – set error returned if the query
processing state is not equal to Annotation.
• EXTFNAPI4_DESCRIBE_INVALID_ATTRIBUTE_VALUE – set error returned if the
UDF tries to set the datatype of a parameter to something other than what it is already
defined as.
Data Type
a_sql_uint32
Description
The width of a parameter to a UDF. EXTFNAPIV4_DESCRIBE_PARM_WIDTH applies
only to scalar parameters. Parameter width is the amount of storage, in bytes, required to store
a parameter of the associated data type.
• Fixed length data types – the bytes required to store the data.
• Variable length data types – the maximum length.
• LOB data types – the amount of storage required to store a handle to the data.
• TIME data types – the amount of storage required to store the encoded time.
Usage
This is a read-only property. The width is derived from the associated column data type. Once
the data type is set, you cannot change the width.
Programming 75
Using In-Database Analytics in Applications
Returns
On success, returns the sizeof(a_sql_uint32).
On failure, returns one of the generic describe_parameter errors or:
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – set error returned if the query
processing state is not equal to Annotation.
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – set error returned if the
describe_buffer is not the size of a_sql_uint32.
• EXTFNAPIV4_DESCRIBE_INVALID_PARAMETER – set error returned if the
specified parameter is a TABLE parameter. This includes parameter 0, or parameter n,
where n is an input table.
• EXTFNAPI4_DESCRIBE_INVALID_ATTRIBUTE_VALUE – set error returned if the
UDF tries to reset the parameter width.
Data Type
a_sql_uint32
Description
The scale of a parameter to a UDF. For arithmetic data types, parameter scale is the number of
digits to the right of the decimal point in a number.
This attribute is invalid for:
• Nonarithmetic data types
• TABLE parameters
Usage
This is a read-only property. The scale is derived from the associated column data type. Once
the data type is set, you cannot change the scale.
Returns
On success, returns sizeof(a_sql_uint32).
On failure, returns one of the generic describe_parameter errors or:
76 SAP Sybase IQ
Using In-Database Analytics in Applications
Data Type
a_sql_byte
Description
True, if the value of a parameter can be NULL at the time of execution. For a TABLE
parameter or parameter 0, the value is false.
Usage
This is a read-only property.
Returns
This is a read-only property, so all attempts to set result in an
EXTFNAPIV4_DESCRIBE_INVALID_ATTRIBUTE error.
Data Type
a_v4_extfn_estimate
Programming 77
Using In-Database Analytics in Applications
Description
Returns the estimated number of distinct values across all invocations. valid only for scalar
parameters.
Usage
This is a read-only property.
Returns
This is a read-only property; all attempts to set result in an
EXTFNAPIV4_DESCRIBE_INVALID_ATTRIBUTE error.
Data Type
a_sql_byte
Description
True, if the parameter is a constant for the statement. Valid only for scalar parameters.
Usage
This is a read-only property.
Returns
This is a read-only property; all attempts to set result in an
EXTFNAPIV4_DESCRIBE_INVALID_ATTRIBUTE error.
Data Type
an_extfn_value
78 SAP Sybase IQ
Using In-Database Analytics in Applications
Description
The value of the parameter if it is known at describe time. Valid only for scalar parameters.
Usage
This is a read-only property.
Returns
This is a read-only property; all attempts to set result in an
EXTFNAPIV4_DESCRIBE_INVALID_ATTRIBUTE error.
Data Type
a_sql_uint32
Description
The number of columns in the table. Only valid for argument 0 and table arguments.
Usage
If the UDF sets this property, the server compares the value with the name of the parameter
supplied in the CREATE PROCEDURE statement. If the two values do not match, the server
returns an error. This allows the UDF to ensure the CREATE PROCEDURE statement has the
same parameter names as the UDF is expecting.
Returns
On success, returns the sizeof(a_sql_uint32).
On failure, returns one of the generic describe_parameter errors or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – set error returned if the
describe_buffer is not the size of size of a_sql_uint32.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – set error returned if the state is not
ANNOTATION.
• EXTFNAPIV4_DESCRIBE_NON_TABLE_PARAMETER – set error returned if the
parameter is not a TABLE parameter.
• EXTFNAPI4_DESCRIBE_INVALID_ATTRIBUTE_VALUE – set error returned if the
UDF tries to reset the number of columns of the specified table.
Programming 79
Using In-Database Analytics in Applications
Data Type
a_sql_a_v4_extfn_estimate
Description
The estimated number of rows in the table. Only valid for argument 0 and table arguments.
Usage
The UDF sets this property for argument 0 if it estimates the number of rows in the result set.
The server uses the estimate during optimization to make query processing decisions. You
cannot set this value for an input table.
If you do not set a value, the server defaults to the number of rows specified by the
DEFAULT_TABLE_UDF_ROW_COUNT option.
Returns
On success, returns a_v4_extfn_estimate.
On failure, returns one of the generic describe_parameter errors or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – set error returned if the
describe_buffer is not the size of a_v4_extfn_estimate.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – set error returned if the state is not
Optimization.
• EXTFNAPIV4_DESCRIBE_NON_TABLE_PARAMETER – get error returned if the
parameter is not a TABLE parameter.
• EXTFNAPIV4_DESCRIBE_INVALID_PARAMETER – get error returned if the
TABLE parameter is not the result table.
• EXTFNAPI4_DESCRIBE_INVALID_ATTRIBUTE_VALUE – get error returned if the
UDF tries to reset the number of columns of the specified table.
80 SAP Sybase IQ
Using In-Database Analytics in Applications
Data Type
a_v4_extfn_orderby_list
Description
The order of rows in the table. This property is only valid for argument 0 and table arguments.
Usage
This attribute allows the UDF code to:
• Determine if the input TABLE parameter has been ordered
• Declare that the result set is ordered.
If the parameter number is 0, then the attribute refers to the outbound result set. If the
parameter is > 0 and the parameter type is a table then the attribute refers to the input TABLE
parameter.
The order is specified by the a_v4_extfn_orderby_list, which is a structure
supporting a list of column ordinals and their associated ascending or descending property. If
the UDF sets the order by property for the outbound result set, the server is then able to
perform order by optimizations. For example, if the UDF produced ascending order on the
first result set column, the server will eliminate a redundant order by request on the same
column.
If the UDF does not set the orderby property on the outbound result set, the server assumes the
data is not ordered.
If the UDF sets the orderby property on the input TABLE parameter, the server guarantees data
ordering for the input data. In this scenario, the UDF describes to the server that the input data
must be ordered. If the server detects a runtime conflict it raises a SQL exception. For
example, when the UDF describes that the first column of the input TABLE parameter must
have ascending order and the SQL statement contains a descending clause, the server raises a
SQL exception.
In the event that the SQL did not contain an ordering clause, the server automatically adds the
ordering to ensure that input TABLE parameter is ordered as required.
Returns
If successful, returns the number of bytes copied from a_v4_extfn_orderby_list.
Programming 81
Using In-Database Analytics in Applications
• Annotation state
• Query optimization state
EXTFNAPIV4_DESCRIBE_PARM_TABLE_PARTITIONBY (Set)
The EXTFNAPIV4_DESCRIBE_PARM_TABLE_PARTITIONBY attribute indicates that
the UDF requires partitioning. Used in a describe_parameter_set scenario.
Data Type
a_v4_extfn_column_list
Description
UDF developers use EXTFNAPIV4_DESCRIBE_PARM_TABLE_PARTITIONBY to
programmatically declare that the UDF requires partitioning before invocation can proceed.
Usage
The UDF can inquire to the partition to enforce it, or to dynamically adapt the partitioning.
The UDF must allocate the a_v4_extfn_column_list, taking into consideration the total
number of columns in the input table, and sending that data to the server.
Returns
On success, returns the size of a_v4_extfn_column_list. This value is equal to:
sizeof(a_v4_extfn_column_list) + sizeof(a_sql_uint32) *
number_of_partition_columns
Example
void UDF_CALLBACK my_tpf_proc_describe( a_v4_extfn_proc_context
*ctx )
{
if( ctx->current_state == EXTFNAPIV4_STATE_ANNOTATION ) {
a_sql_int32 rc = 0;
a_v4_extfn_column_list pbcol =
{ 1, // 1 column in the partition by list
2 }; // column index 2 requires partitioning
82 SAP Sybase IQ
Using In-Database Analytics in Applications
EXTFNAPIV4_DESCRIBE_PARM_TABLE_PARTITIONBY,
&pbcol,
sizeof(pbcol) );
if( rc == 0 ) {
ctx->set_error( ctx, 17000,
“Runtime error, unable set partitioning requirements for
column.” );
}
}
}
Data Type
a_sql_byte
Description
Indicates that the consumer wants to rewind an input table. Valid only for table input
arguments. By default, this property is false.
Usage
If the UDF requires input table rewind capability, the UDF must set this property during
Optimization.
Returns
On success, returns sizeof(a_sql_byte).
On failure, returns one of the generic describe_parameter errors, or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – set error returned if the
describe_buffer is not the size of a_sql_byte.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – set error returned if the state is not
equal to Optimization.
• EXTFNAPIV4_DESCRIBE_INVALID_PARAMETER – set error returned if the UDF
attempts to set this attribute on parameter 0.
• EXTFNAPIV4_DESCRIBE_NON_TABLE_PARAMETER – set error returned if the
UDF attempts to set this attribute on a parameter that is not a table.
• EXTFNAPIV4_DESCRIBE_INVALID_ATTRIBUTE_VALUE – set error returned if
the UDF attempts to set this attribute to a value other than 0 or 1.
Programming 83
Using In-Database Analytics in Applications
• Optimization state
Example
In this example, when the function my_udf_describe is called during the Optimization state,
the call to describe_parameter_set informs the producer of the table input parameter
1 that a rewind may be required.
Sample procedure definition:
CREATE PROCEDURE my_udf(IN t TABLE(c1 INT))
RESULT (x INT)
EXTERNAL NAME ‘my_udf@myudflib’;
Sample _describe_extfn API function code fragment:
my_udf_describe(a_v4_extfn_proc_context *cntxt)
{
if( cntxt->current_state == EXTFNAPIV4_STATE_OPTIMIZATION ) {
a_sql_byte rewind_required = 1;
a_sql_int32 ret = 0;
Data Type
a_sql_byte
Description
Indicates whether a producer can support rewind. Valid only for table arguments.
You must also provide an implementation of the rewind table callback (_rewind_extfn() ), if
you plan on setting DESCRIBE_PARM_TABLE_HAS_REWIND to true. The server cannot
execute the UDF if you do not provide the callback method.
Usage
A UDF sets this property during the Optimization state if it can provide rewind capability for
its result table at no cost. If it is expensive for the UDF to provide rewind, do not set this
property, or set it to 0. If set to 0, the server provides rewind support.
84 SAP Sybase IQ
Using In-Database Analytics in Applications
Returns
On success, returns sizeof(a_sql_byte).
On failure, returns one of the generic describe_parameter errors, or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – set error returned if the
describe_buffer is not the size of a_sql_byte.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – set error returned if the state is not
equal to Optimization.
• EXTFNAPIV4_DESCRIBE_NON_TABLE_PARAMETER – set error returned if the
UDF attempts to set this attribute on a parameter that is not a table.
• EXTFNAPIV4_DESCRIBE_INVALID_PARAMETER – set error returned if the
specified argument is not the result table.
• EXTFNAPIV4_DESCRIBE_INVALID_ATTRIBUTE_VALUE – set error returned if
the UDF attempts to set this attribute to a value other than 0 or 1.
Data Type
a_v4_extfn_column_list
Description
The list of output table columns that are not going to be consumed by the server or the UDF.
For the output TABLE parameter, the UDF normally produces the data for all the columns, and
the server consumes all the columns. The same holds true for the input TABLE parameter
where the server normally produces the data for all the columns, and the UDF consumes all the
columns.
However, in some cases the server, or the UDF, may not consume all the columns. The best
practice in such a case is that the UDF performs a GET for the output table on the describe
attribute EXTFNAPIV4_DESCRIBE_PARM_TABLE_UNUSED_COLUMNS. This action
queries the server for the list of output table columns which are not going to be consumed by
the server. The list can then be used by the UDF when populating the column data for the
output table; that is, the UDF skips populating data for unused columns.
In summary, for the output table the UDF polls the list of unused columns. For the input table,
the UDF pushes the list of unused columns.
Programming 85
Using In-Database Analytics in Applications
Usage
The UDF sets this property during Optimization if it is not going to use certain columns of the
input TABLE parameter. The UDF must allocate a a_v4_extfn_column_list that
includes all the columns of the output table, and then must pass it to the server. The server then
marks all the un-projected column ordinals as 1. The server copies the list into its internal data
structure.
Returns
On success, returns the size of the column list: sizeof(a_v4_extfn_column_list)
+ sizeof(a_sql_uint32) * number result columns.
On failure, returns one of the generic describe_parameter errors or:
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – set error returned if the state is not
Optimization.
• EXTFNAPIV4_DESCRIBE_INVALID_PARAMETER – set error returned if the UDF
attempts to get this attribute on an input table.
• EXTFNAPIV4_DESCRIBE_NON_TABLE_PARAMETER – set error returned if the
UDF attempts to set this attribute on a parameter that is not a table.
*describe_udf_get
The describe_udf_get v4 API method gets UDF properties from the server.
Declaration
a_sql_int32 (SQL_CALLBACK *describe_udf_get)(
a_v4_extfn_proc_context *cntxt,
a_v4_extfn_describe_udf_type describe_type,
void *describe_buffer,
size_t describe_buffer_len );
Parameters
Parameter Description
cntxt The procedure context object for this UDF.
86 SAP Sybase IQ
Using In-Database Analytics in Applications
Parameter Description
describe_buffer A structure that holds the describe information
for the specified property to set on the server. The
specific structure or data type is indicated by the
describe_type parameter.
Returns
On success, returns 0 or the number of bytes written to the describe_buffer. A value of 0
indicates that the server was unable to get the attribute but no error condition occurred. If an
error occurred, or no property was retrieved, this function returns one of the generic
describe_udf errors.
Data Type
a_sql_uint32
Description
The number of parameters supplied to the UDF.
Usage
Gets the number of parameters as defined in the CREATE PROCEDURE statement.
Returns
On success, returns the sizeof(a_sql_uint32).
On failure, returns one of the generic describe_udf errors, or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – get error returned if the
describe buffer is not the size of a_sql_uint32.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – get error returned if the phase is not
greater than Initial.
Programming 87
Using In-Database Analytics in Applications
*describe_udf_set
The describe_udf_set v4 API method sets UDF properties on the server.
Declaration
a_sql_int32 (SQL_CALLBACK *describe_udf_set)(
a_v4_extfn_proc_context *cntxt,
a_v4_extfn_describe_udf_type describe_type,
const void *describe_buffer,
size_t describe_buffer_len );
Parameters
Parameter Description
cntxt The procedure context object for this UDF.
Returns
On success, returns the number of bytes written to the describe_buffer. If an error occurs, or
no property is retrieved, this function returns one of the generic describe_udf errors.
If an error occurs, or no property is retrieved, this function returns one of the generic
describe_udf errors, or:
• EXTFNAPIV4_DESCRIBE_INVALID_PARAMETER – set error returned if any of the
cntxt or describe_buffer arguments are NULL or if describe_buffer_length is 0.
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – set error returned if there
is a discrepancy between the requested attribute’s size and the supplied
describe_buffer_length.
88 SAP Sybase IQ
Using In-Database Analytics in Applications
Data Type
a_sql_uint32
Description
The number of parameters supplied to the UDF.
Usage
If the UDF sets this property, the server compares the value with the number of parameters
supplied in the CREATE PROCEDURE statement. If the two values do not match, the server
returns a SQL error. This allows the UDF to ensure the CREATE PROCEDURE statement has
the same number of parameters expected by the UDF.
Returns
On success, returns the sizeof(a_sql_uint32).
On failure, returns one of the generic describe_udf errors, or:
• EXTFNAPIV4_DESCRIBE_BUFFER_SIZE_MISMATCH – Set error returned if the
describe buffer is not the size of a_sql_uint32.
• EXTFNAPIV4_DESCRIBE_INVALID_STATE – Set error returned if the state is not
equal to Annotation.
• EXTFNAPIV4_DESCRIBE_INVALID_ATTRIBUTE_VALUE – set error returned if
the UDF tries to reset the parameter datatype.
Programming 89
Using In-Database Analytics in Applications
Implementation
typedef enum a_v4_extfn_describe_col_type {
EXTFNAPIV4_DESCRIBE_COL_NAME,
EXTFNAPIV4_DESCRIBE_COL_TYPE,
EXTFNAPIV4_DESCRIBE_COL_WIDTH,
EXTFNAPIV4_DESCRIBE_COL_SCALE,
EXTFNAPIV4_DESCRIBE_COL_CAN_BE_NULL,
EXTFNAPIV4_DESCRIBE_COL_DISTINCT_VALUES,
EXTFNAPIV4_DESCRIBE_COL_IS_UNIQUE,
EXTFNAPIV4_DESCRIBE_COL_IS_CONSTANT,
EXTFNAPIV4_DESCRIBE_COL_CONSTANT_VALUE,
EXTFNAPIV4_DESCRIBE_COL_IS_USED_BY_CONSUMER,
EXTFNAPIV4_DESCRIBE_COL_MINIMUM_VALUE,
EXTFNAPIV4_DESCRIBE_COL_MAXIMUM_VALUE,
EXTFNAPIV4_DESCRIBE_COL_VALUES_SUBSET_OF_INPUT,
EXTFNAPIV4_DESCRIBE_COL_LAST
} a_v4_extfn_describe_col_type;
Members Summary
Member Description
EXTFNAPIV4_DESCRIBE_COL_NAME Column name (valid identifier).
90 SAP Sybase IQ
Using In-Database Analytics in Applications
Member Description
EXTFNAPIV4_DESCRIBE_COL_IS_USED_BY_CONSUM- True, if column is needed by the
ER consumer of the table.
Implementation
typedef enum a_v4_extfn_describe_parm_type {
EXTFNAPIV4_DESCRIBE_PARM_NAME,
EXTFNAPIV4_DESCRIBE_PARM_TYPE,
EXTFNAPIV4_DESCRIBE_PARM_WIDTH,
EXTFNAPIV4_DESCRIBE_PARM_SCALE,
EXTFNAPIV4_DESCRIBE_PARM_CAN_BE_NULL,
EXTFNAPIV4_DESCRIBE_PARM_DISTINCT_VALUES,
EXTFNAPIV4_DESCRIBE_PARM_IS_CONSTANT,
EXTFNAPIV4_DESCRIBE_PARM_CONSTANT_VALUE,
EXTFNAPIV4_DESCRIBE_PARM_TABLE_NUM_COLUMNS,
EXTFNAPIV4_DESCRIBE_PARM_TABLE_NUM_ROWS,
EXTFNAPIV4_DESCRIBE_PARM_TABLE_ORDERBY,
EXTFNAPIV4_DESCRIBE_PARM_TABLE_PARTITIONBY,
EXTFNAPIV4_DESCRIBE_PARM_TABLE_REQUEST_REWIND,
EXTFNAPIV4_DESCRIBE_PARM_TABLE_HAS_REWIND,
EXTFNAPIV4_DESCRIBE_PARM_TABLE_UNUSED_COLUMNS,
EXTFNAPIV4_DESCRIBE_PARM_LAST
} a_v4_extfn_describe_parm_type;
Programming 91
Using In-Database Analytics in Applications
Members Summary
Member Description
EXTFNAPIV4_DESCRIBE_PARM_NAME Parameter name (valid iden-
tifier).
These selectors can retrieve or set properties of a TABLE parameter. These enumerator values cannot
be used with scalar parameters:
92 SAP Sybase IQ
Using In-Database Analytics in Applications
Member Description
EXTFNAPIV4_DESCRIBE_PARM_TABLE_UNUSED_COL- The list of output table col-
UMNS umns that are not going to be
consumed by the server or the
UDF.
Implementation
typedef enum a_v4_extfn_describe_return {
EXTFNAPIV4_DESCRIBE_NOT_AVAILABLE = 0, // the specified operation has no
meaning either for this attribute or in
length is insufficient.
EXTFNAPIV4_DESCRIBE_INVALID_PARAMETER = -2, // the provided parameter number
is invalid
EXTFNAPIV4_DESCRIBE_INVALID_COLUMN = -3, // the column number is invalid
for this TABLE parameter
EXTFNAPIV4_DESCRIBE_INVALID_STATE = -4, // the describe method call is not
valid in the present state
EXTFNAPIV4_DESCRIBE_INVALID_ATTRIBUTE = -5, // the attribute is known but not
appropriate for this object
EXTFNAPIV4_DESCRIBE_UNKNOWN_ATTRIBUTE = -6, // the identified attribute is
not known to this server version
EXTFNAPIV4_DESCRIBE_NON_TABLE_PARAMETER = -7, // the specified parameter is
not a TABLE parameter (for describe_col_get()
or set())
EXTFNAPIV4_DESCRIBE_INVALID_ATTRIBUTE_VALUE = -8, // the specified attribute
value is illegal
EXTFNAPIV4_DESCRIBE_LAST = -9
} a_v4_extfn_describe_return;
Members Summary
Member Re- Description
turn
Value
EXTFNAPIV4_DESCRIBE_NOT_AVAILABLE 0 The specified operation
has no meaning either for
this attribute or in the cur-
rent context.
Programming 93
Using In-Database Analytics in Applications
Description
The return value of a_v4_extfn_proc_context.describe_xxx_get() and
a_v4_extfn_proc_context.describe_xxx_set() is a signed integer. If the
result is positive, the operation succeeds, and the value is the number of bytes copied. If the
94 SAP Sybase IQ
Using In-Database Analytics in Applications
return value is less or equal to zero, the operation does not succeed, and the return value is one
of the a_v4_extfn_describe_return values.
Implementation
typedef enum a_v4_extfn_describe_udf_type {
EXTFNAPIV4_DESCRIBE_UDF_NUM_PARMS,
EXTFNAPIV4_DESCRIBE_UDF_LAST
} a_v4_extfn_describe_udf_type;
Members Summary
Member Description
EXTFNAPIV4_DE- The number of parameters supplied to the UDF.
SCRIBE_UDF_NUM_PARMS
Description
The a_v4_extfn_proc_context.describe_udf_get() method is used by the
UDF to retrieve properties, and the
a_v4_extfn_proc_context.describe_udf_set() method is used by the UDF
to set properties about the UDF as a whole. The a_v4_extfn_describe_udf_type
enumerator selects the logical property the UDF retrieves or sets.
Implementation
typedef enum a_v4_extfn_state {
EXTFNAPIV4_STATE_INITIAL, // Server initial state,
not used by UDF
EXTFNAPIV4_STATE_ANNOTATION, // Annotating parse
tree with UDF reference
EXTFNAPIV4_STATE_OPTIMIZATION, // Optimizing
EXTFNAPIV4_STATE_PLAN_BUILDING, // Building execution
plan
EXTFNAPIV4_STATE_EXECUTING, // Executing UDF and
fetching results from UDF
EXTFNAPIV4_STATE_LAST
} a_v4_extfn_state;
Programming 95
Using In-Database Analytics in Applications
Members Summary
Member Description
EXTFNAPIV4_STATE_INITIAL Server initial phase. The only UDF method that is
called during this query processing phase is
_start_extfn.
EXTFNAPIV4_STATE_ANNOTATION Annotating parse tree with UDF reference. The
UDF is not invoked during this phase.
Description
The a_v4_extfn_state enumeration indicates which stage of UDF execution the server
is in. When the server makes a transition from one phase to the next, the server informs the
UDF it is leaving the previous phase by calling the UDF’s _leave_state_extfn
function. The server informs the UDF it is entering the new phase by calling the UDF’s
_enter_state_extfn function.
The query processing phase of a UDF restricts the operations that the UDF can perform. For
example, in the Annotation phase, the UDF can retrieve the data types only for constant
parameters.
96 SAP Sybase IQ
Using In-Database Analytics in Applications
Method Summary
Method Description
_start_extfn Allocates a structure and stores its address in the
_user_data field in the
a_v4_extfn_proc_context.
_finish_extfn Deallocates a structure whose address was stored
in the user_data field in the
a_v4_extfn_proc_context.
_evaluate_extfn Required function pointer to be called for each
invocation of the function on a new set of argu-
ment values.
_start_extfn
Use the _start_extfn v4 API method as an optional pointer to an initializer function, for
which the only argument is a pointer to a_v4_extfn_proc_context structure.
Declaration
_start_extfn(
a_v4_extfn_proc_context *
)
Usage
Use the _start_extfn method to allocate a structure and store its address in the
_user_data field in the a_v4_extfn_proc_context. This function pointer must be
set to the null pointer if there is no need for any initialization.
Programming 97
Using In-Database Analytics in Applications
Parameters
Parameter Description
cntxt The procedure context object.
_finish_extfn
Use the _finish_extfn v4 API method as an optional pointer to a shutdown function, for
which the only argument is a pointer to a_v4_extfn_proc_context.
Declaration
_finish_extfn(
a_v4_extfn_proc_context *cntxt,
)
Usage
The _finish_extfn API deallocates a structure for which the address was stored in the
user_data field in the a_v4_extfn_proc_context. This function pointer must be
set to the null pointer if there is no need for any cleanup.
Parameters
Parameter Description
cntxt The procedure context object.
_evaluate_extfn
Use the _evaluate_extfn v4 API method as a required function pointer that is called for
each invocation of the function on a new set of argument values.
Declaration
_evaluate_extfn(
a_v4_extfn_proc_context *cntxt,
void *args_handle
)
Usage
The _evaluate_extfn function must describe to the server how to fetch results by filling
in the a_v4_extfn_table_func portion of the a_v4_extfn_table structure and
use the set_value method on the context with argument zero to send this information to the
server. This function must also inform the server of its output schema by filling in the
a_v4_extfn_value_schema of the a_v4_extfn_table structure before calling
set_value on argument 0. It can access its input argument values via the get_value
callback function. Both constant and nonconstant arguments are available to the UDF at this
time.
98 SAP Sybase IQ
Using In-Database Analytics in Applications
Parameters
Parameter Description
cntxt The procedure context object.
_describe_extfn
_describe_extfn is called at the beginning of each state to allow the server to get and set
logical properties. The UDF can do this by using the six describe methods
(describe_parameter_get, describe_parameter_set,
describe_column_get, describe_column_set, describe_udf_get, and
describe_udf_set) in the a_v4_proc_context object.
See Describe API on page 25.
_enter_state_extfn
The UDF can implement the _enter_state_extfn v4 API method as an optional entry
point to be notified whenever the UDF enters a new state.
Declaration
_enter_state_extfn(
a_v4_extfn_proc_context *cntxt,
)
Usage
The UDF can use this notification to allocate structures.
Parameters
Parameter Description
cntxt The procedure context object.
_leave_state_extfn
The _leave_state_extfn v4 API method is an optional entry point the UDF can
implement to receive a notification when the UDF moves out of a query processing state.
Declaration
_leave_state_extfn(
a_v4_extfn_proc_context *cntxt,
)
Usage
The UDF can use this notification to release memory or resources needed for the state.
Programming 99
Using In-Database Analytics in Applications
Parameters
Parameter Description
cntxt The procedure context object.
Implementation
typedef struct a_v4_extfn_proc_context {
.
.
.
} a_v4_extfn_proc_context;
Method Summary
Re- Method Description
turn
Type
short get_value Gets input arguments to the UDF.
short get_value_is_constant Allows the UDF to ask whether a given argument is a con-
stant.
a_sql_ get_is_cancelled Call the get_is_cancelled callback every second or two to see
uint32 if the user has interrupted the current statement.
short set_error Rolls back the current statement and generates an error.
void free Free the memory allocated by alloc() for the specified life-
time.
short set_cannot_be_distrib- Disables distribution at the UDF level even if the library is
uted distributable.
_executionMode a_sql_ui Indicates the debug/trace level requested via the Exter-
nt32 nal_UDF_Execution_Mode option. This is a read-only field.
current_state a_sql_ui The current_state attribute reflects the current execution mode of
nt32 the context. This can be queried from functions such as _de-
scribe_extfn to determine what course of action to take.
Description
In addition to retaining context information from the server and the UDF, the structure
a_v4_extfn_proc_context allows the UDF to call back into the server to perform
Programming 101
Using In-Database Analytics in Applications
certain actions. The UDF can store private data in this structure in the _user_data member.
An instance of this structure gets passed to the functions in the a_v4_extfn_proc method
by the server. User data is not maintained until after the server reaches the Annotation state.
get_value
Use the get_value v4 API method to obtain the values of input arguments sent to the UDF
in a SQL query.
Declaration
short get_value(
void * arg_handle,
a_sql_uint32 arg_num,
an_extfn_value *value
)
Usage
The get_value API is used in an evaluation method to retrieve the value of each input
argument to the UDF. For narrow argument data types (>32K), a call to get_value is
sufficient to retrieve the entire argument value.
The get_value API can be called from any API that has access to the arg_handle
pointer. This includes API functions that take a_v4_table_context as a parameter. The
a_v4_table_context has an args_handle member variable that can be used for this
purpose.
For all fixed-length data types, the data is available in the returned value and no further calls
are necessary to obtain all of the data. The producer can decide what the maximum length is
that is returned entirely in the call to get_value method. All fixed length data types should
be guaranteed to fit in a single contiguous buffer. For variable-length data, the limit is
producer-dependant.
For nonfixed-length data types, and depending on the length of the data, a blob may need to be
created using the get_blob method to get the data. You can use the macro
EXTFN_IS_INCOMPLETE on the value returned by get_value to determine whether a blob
object is required. If EXTFN_IS_INCOMPLETE evaluates to true, a blob is required.
For input arguments that are tables, the type is AN_EXTFN_TABLE. For this type of argument,
you must create a result set using the open_result_set method to read values in from the
table.
If a UDF requires the value of an argument prior to the _evaluate_extfn API being
called, then the UDF should implement the _describe_extfn API. From the
_describe_extfn API, the UDF can obtain the value of constant expressions using the
describe_parameter_get method.
Parameters
Parameter Description
arg_num The index of the argument to get a value for. The argument index starts at 1.
Returns
1 if successful, 0 otherwise.
an_extfn_value Structure
The an_extfn_value structure represents the value of an input argument returned by the
get_value API.
This code shows the declaration of the an_extfn_value structure:
short typedef struct an_extfn_value {
void* data;
a_sql_uint32 piece_len,
an_extfn_value *value {
a_sql_uint32 total_len;
a_sql_uint32 remain_len;
} len;
a_sql_data_type type;
} an_extfn_value;
This table describes what the returned values of an_extfn_value object look like after calling
the get_value method:
Value Re- EXTFN_IS_IN total_len piece_len data
turned by COMPLETE
get_value API
null FALSE 0 0 null
Programming 103
Using In-Database Analytics in Applications
The type field of an_extfn_value contains the data type of the value. For UDFs that have tables
as input arguments, the data type of that argument is DT_EXTFN_TABLE. For v4 Table UDFs,
the remain_len field is not used.
get_value_is_constant
Use the get_value_is_constant v4 API method to determine whether the specified
input argument value is a constant.
Declaration
short get_value_is_constant(
void * arg_handle,
a_sql_uint32 arg_num,
an_extfn_value *value_is_constant
)
Usage
The UDF can ask whether a given argument is a constant. This is useful for optimizing a UDF,
for example, where work can be performed once during the first call to the
_evaluate_extfn function, rather than for every evaluation call.
Parameters
Parameter Description
arg_num The index value of the input argument being retrieved. Index values are 1..N.
Returns
1 if successful, 0 otherwise.
set_value
Use the set_value v4 API method to describe to the consumer how many columns the
result set has and how data should be read.
Declaration
short set_value(
void * arg_handle,
a_sql_uint32 arg_num,
an_extfn_value *value
)
Usage
This method is used by the UDF in the _evaluate_extfn API. The UDF must call the
set_value method to tell the consumer how many columns are in the result set and what set
of a_v4_extfn_table_func functions the UDF supports.
For the set_value API, the UDF provides an appropriate arg_handle pointer via the
_evaluate_extfnAPI, or from the args_handle member of
a_v4_extfn_table_context structure.
The value argument for the set_value method must be of type DT_EXTFN_TABLE for v4
Table UDFs.
Parameters
Parameter Description
arg_num The index of the argument to set a value for. The only supported argument is 0.
Returns
1 if successful, 0 otherwise.
get_is_cancelled
Use the get_is_cancelled v4 API method to determine whether the statement has been
cancelled.
Declaration
short get_is_cancelled(
a_v4_extfn_proc_context * cntxt,
Usage
If a UDF entry point is performing work for an extended period of time (many seconds), it
should, if possible, call the get_is_cancelled callback every second or two to see if the
user has interrupted the current statement. If the statement has been interrupted, a nonzero
value is returned and the UDF entry point should then immediately return. Call the
_finish_extfn function to perform necessary cleanup. Do not subsequently call any
other UDF entry points.
Programming 105
Using In-Database Analytics in Applications
Parameters
Parameter Description
Returns
A nonzero value, if the statement is interrupted.
set_error
Use the set_error v4 API method to communicate an error back to the server and
eventually to the user.
Declaration
void set_error(
a_v4_extfn_proc_context * cntxt,
a_sql_uint32 error_number,
const char *error_desc_string
)
Usage
Call the set_error API, if a UDF entry point encounters an error that should send an error
message to the user and shut down the current statement. When called, set_error API rolls
back the current statement and the user sees “Error raised by user-defined
function: <error_desc_string>”. The SQLCODE is the negated form of the
supplied <error_number>.
To avoid collisions with existing error codes, UDFs should generate error numbers between
17000 and 99999. If a number outside this range is provided, the statement is still rolled back,
but the error message is "Invalid error raised by user-defined
function: (<error_number>) <error_desc_string>" with a SQLCODE of
-1577. The maximum length of error_desc_string is 140 characters.
After a call to set_error is made, the UDF entry point should immediately perform a
return; eventually the _finish_extfn function is called to perform necessary cleanup. Do
not subsequently call any other UDF entry points.
Parameters
Parameter Description
Parameter Description
log_message
Use the log_message v4 API method to to send a message to the server's message log.
Declaration
short log_message(
const char *msg,
short msg_length
)
Usage
The log_message method writes a message to the message log. The message string must be
a printable text string no longer than 255 bytes; longer messages may be truncated.
Parameters
Parameter Description
convert_value
Use the convert_value v4 API method to convert data types.
Declaration
short convert_value(
an_extfn_value *input,
an_extfn_value *output
)
Usage
. The primary use of the convert_value API is the converting between DT_DATE,
DT_TIME, and DT_TIMESTAMP, and DT_TIMESTAMP_STRUCT. An input and output
an_extfn_value is passed to the function.
Input Parameters
Parameter Description
an_extfn_value.data Input data pointer
Programming 107
Using In-Database Analytics in Applications
Parameter Description
an_extfn_value.total_len Length of input data
Output Parameters
Parameter Description
an_extfn_value.data UDF supplied output data point
Returns
1 if successful, 0 otherwise.
get_option
The get_option v4 API method gets the value of a settable option.
Declaration
short get_option(
a_v4_extfn_proc_context * cntxt,
char *option_name,
an_extfn_value *output
)
Parameters
Parameter Description
cntxt The procedure context object
output
• an_extfn_value.data – UDF sup-
plied output data pointer
• an_extfn_value.piece_len –
maximum length of output data
• an_extfn_value.total_len –
server set length of converted output
• an_extfn_value.type – server set
data type of value
Returns
1 if successful, 0 otherwise.
alloc
The alloc v4 API method allocates a block of memory.
Declaration
void*alloc(
a_v4_extfn_proc_context *cntxt,
size_t len
)
Usage
Allocates a block of memory of length at least len. The returned memory is 8-byte aligned.
Tip: Use the alloc() method as your only means of memory allocation, which allows the
server to keep track of how much memory is used by external routines. The server can adapt
other memory users, track leaks, and provide improved diagnostics and monitoring.
Memory tracking is enabled only when external_UDF_execution_mode is set to a value of 1
or 2 (validation mode or tracing mode).
Parameters
Parameter Description
cntxt The procedure context object
free
The free v4 API method frees an allocated block of memory.
Declaration
void free(
a_v4_extfn_proc_context *cntxt,
void *mem
)
Usage
Frees the memory allocated by alloc() for the specified lifetime.
Memory tracking is enabled only when external_UDF_execution_mode is set to a value of 1
or 2 (validation mode or tracing mode).
Programming 109
Using In-Database Analytics in Applications
Parameters
Parameter Description
cntxt The procedure context object
open_result_set
The open_result_set v4 API method opens a result set for a table value.
Declaration
short open_result_set(
a_v4_extfn_proc_context *cntxt,
a_v4_extfn_table *table,
a_v4_extfn_table_context **result_set
)
Usage
open_result_set opens a result set for a table value. A UDF can open a result set to read
rows from an input parameter of type DT_EXTFN_TABLE. The server (or another UDF) can
open a result set to read rows from the UDF.
Parameters
Parameter Description
cntxt The procedure context object
Returns
1 if successful, 0 otherwise.
See the fetch_block and fetch_into v4 API method descriptions for examples of the
use of open_result_set.
close_result_set
The close_result_set v4 API method closes an open result set.
Declaration
short close_result_set(
a_v4_extfn_proc_context *cntxt,
a_v4_extfn_table_context *result_set
)
Usage
You can only use close_result_set once per result set.
Parameters
Parameter Description
cntxt The procedure context object
Returns
1 if successful, 0 otherwise.
get_blob
Use the get_blob v4 API method to retrieve an input blob parameter.
Declaration
short get_blob(
void *arg_handle,
a_sql_uint32 arg_num,
a_v4_extfn_blob **blob
)
Usage
Use get_blob to retrieve a blob input parameter after calling get_value(). Use the
macro EXTFN_IS_INCOMPLETE to determine if a blob object is required to read the data
for the value returned from get_value(), if piece_len < total_len. The blob object is
returned as an output parameter and is owned by the caller.
get_blob obtains a blob handle that can be used to read the contents of the blob. Call this
method only on columns that contain blob objects.
Parameters
Parameter Description
Returns
1 if successful, 0 otherwise.
Programming 111
Using In-Database Analytics in Applications
set_cannot_be_distributed
The set_cannot_be_distributed v4 API method disables distributions at the UDF
level, even if the distribution criteria are met at the library level.
Declaration
void set_cannot_be_distributed( a_v4_extfn_proc_context *cntxt)
Usage
In the default behavior, if the library is distributable, then the UDF is distributable. Use
set_cannot_be_distributed in the UDF to push the decision to disable distribution
to the server.
Implementation
typedef struct an_extfn_license_info {
short version;
} an_extfn_license_info;
info Value the UDF sets for additional library information such as library version
and build numbers.
key (Design partners only) An SAP-supplied license key. The key is a 26-character
array.
Implementation
typedef struct a_v4_extfn_estimate {
double value;
double confidence;
} a_v4_extfn_estimate;
Implementation
typedef struct a_v4_extfn_orderby_list {
a_sql_uint32 number_of_elements;
a_v4_extfn_order_el order_elements[1]; // there are
number_of_elements entries
} a_v4_extfn_orderby_list;
Programming 113
Using In-Database Analytics in Applications
Description
There are number_of_elements entries, each with a flag indicating whether the element is
ascending or descending, and a column index indicating the appropriate column in the
associated table.
Implementation
typedef enum a_v4_extfn_partitionby_col_num {
EXTFNAPIV4_PARTITION_BY_COLUMN_NONE = -1, // NO PARTITION
BY
EXTFNAPIV4_PARTITION_BY_COLUMN_ANY = 0, // PARTITION BY
ANY
// + INTEGER representing a specific
column ordinal
} a_v4_extfn_partitionby_col_num;
Members Summary
Member of a_v4_extfn_partition- Val- Description
by_col_num Enumerated Type ue
EXTFNAPIV4_PARTITION_BY_COL- -1 NO PARTITION BY
UMN_NONE
Column Ordinal Number N>0 Ordinal for the table column number
to partition on
Description
This structure allows the UDF to programmatically describe the partitioning and the column
to partition on.
Use this enumeration when populating the a_v4_extfn_column_list
number_of_columns field. When describing partition by support to the server, the UDF
sets the number_of_columns to one of the enumerated values, or to a positive integer
representing the number of column ordinals listed. For example, to describe to the server that
no partitioning is supported, create the structure as:
a_v4_extfn_column_list nopby = {
EXTFNAPIV4_PARTITION_BY_COLUMN_NONE,
0
};
Row (a_v4_extfn_row)
Use the a_v4_extfn_row structure to represent the data in a single row.
Implementation
/* a_v4_extfn_row - */
typedef struct a_v4_extfn_row {
a_sql_uint32 *row_status;
a_v4_extfn_column_data *column_data;
} a_v4_extfn_row;
row_status a_sql_uint32 * The status of the row. Set to 1 for existing rows and 0
otherwise.
Description
The row structure contains information for a specific row of columns. This structure defines
the status of an individual row and includes a pointer to the individual columns within the row.
The row status is a flag that indicates the existence of a row. The row status flag can be altered
by nested fetch calls without requiring manipulation of the row block structure.
The row_status flag set as 1 indicates that the row is available and can be included in the result
set. The row_status set as 0 means the row should be ignored. This is useful when the TPF is
acting as a filter because TPF may pass through rows of an input table to the result set, but it
may also want to skip certain rows, which it can do by setting a status of 0 for those rows.
Programming 115
Using In-Database Analytics in Applications
Implementation
/* a_v4_extfn_row_block - */
typedef struct a_v4_extfn_row_block {
a_sql_uint32 max_rows;
a_sql_uint32 num_rows;
a_v4_extfn_row *row_data;
} a_v4_extfn_row_block;
max_rows a_sql_uint32 The maximum number of rows this row block can handle
num_rows a_sql_uint32 Must be less than or equal to the maximum of rows the row
block contains
Description
The row block structure is utilized by the fetch_into and fetch_block methods to
allow the production and consumption of data. The allocator sets the maximum number of
rows. The producer icorrectly sets the number of rows. The data consumer should not attempt
to read more than number of rows produced.
The owner of the row_block structure determines the value of max_rows data member. For
example, when a table UDF is implementing fetch_into, the value of max_rows is
determined by the server as the number of rows that can fit into 128K of memory. However,
when a table UDF is implementing fetch_block, the table UDF itself determines the value
of max_rows.
Table (a_v4_extfn_table)
Use the a_v4_extfn_table structure to represent how data is stored in a table and how
the consumer fetches that data.
Implementation
typedef struct a_v4_extfn_table {
a_v4_extfn_table_func *func;
a_sql_uint32 number_of_columns;
} a_v4_extfn_table;
Implementation
typedef struct a_v4_extfn_table_context {
// size_t struct_size;
The row_block parameter is in/out. The first call should point to a NULL row
block.
The fetch_block() call sets row_block to a block that can be consumed, and this
block
should be passed on the next fetch_block() call.
*/
short (UDF_CALLBACK *fetch_block)(a_v4_extfn_table_context *cntxt,
a_v4_extfn_row_block **row_block);
/* get_blob() - If the specified column has a blob object, return it. The blob
is returned as an out parameter and is owned by the caller. This method should
only be called on a column that contains a blob. The helper macro
EXTFN_COL_IS_BLOB can
be used to determine whether a column contains a blob.
*/
short (UDF_CALLBACK *get_blob)(a_v4_extfn_table_context *cntxt,
a_v4_extfn_column_data *col,
a_v4_extfn_blob **blob);
/* The following fields are reserved for future use and must be initialized to NULL.
*/
void *reserved1_must_be_null;
void *reserved2_must_be_null;
void *reserved3_must_be_null;
Programming 117
Using In-Database Analytics in Applications
void *reserved4_must_be_null;
void *reserved5_must_be_null;
a_v4_extfn_proc_context *proc_context;
void *args_handle; // use in
a_v4_extfn_proc_context::get_value() etc.
a_v4_extfn_table *table;
void *user_data;
void *server_internal_use;
/* The following fields are reserved for future use and must be initialized to NULL.
*/
void *reserved6_must_be_null;
void *reserved7_must_be_null;
void *reserved8_must_be_null;
void *reserved9_must_be_null;
void *reserved10_must_be_null;
} a_v4_extfn_table_context;
Method Summary
Data Method Description
Type
short fetch_into Fetch into a specified row_block
short rewind Restarts the result set at the beginning of the table
short get_blob Return a blob object, if the specified column has a blob object
table a_v4_extfn_table * Points to the open result set table. This is populated after
a_v4_extfn_proc_context open_re-
sult_set has been called.
user_data void * This data pointer can be filled in by any usage with whatever
context data the external routine requires.
Description
The a_v4_extfn_table_context structure acts as a middle layer between the
producer and the consumer to help manage the data, when the consumer and producer require
separate formats.
A UDF can read rows from an input TABLE parameter using
a_v4_extfn_table_context. The server or another UDF can read rows from the result
table of a UDF using a_v4_extfn_table_context.
The server implements the methods of a_v4_extfn_table_context, which gives the
server an opportunity to resolve impedance mismatches.
fetch_into
The fetch_into v4 API method fetches data into a specified row block.
Declaration
short fetch_into(
a_v4_extfn_table_context *cntxt,
a_v4_extfn_row_block *)
Usage
The fetch_into method is useful when the producer does not know how data should be
arranged in memory. This method is used as an entry point when the consumer has a transfer
area with a specific format. The fetch_into() function writes the fetched rows into the
provided row block. This method is part of the a_v4_extfn_table_context structure.
Use fetch_into when the consumer owns the memory for the data transfer area and
requests that the producer use this area. You use the fetch_into method when the
consumer cares about how the data transfer area is set up and it is up to the producer to perform
the necessary data copying into this area.
Parameters
Parameter Description
cntxt The table context object obtained from the
open_result_set API
row_block The row block object to fetch into
Returns
1 if successful, 0 otherwise.
If the UDF returns 1, the consumer knows that there are more rows left and the fetch_into
method should be called again. However, a UDF returning a value of 0 indicates that there are
no more rows and a call to the fetch_into method is unnecessary.
Programming 119
Using In-Database Analytics in Applications
Consider the following procedure definition, which is an example of a TPF function that
consumes an input parameter table and produces it as a result table. Both are instances of SQL
values that are obtained and returned through the get_value and set_value v4 API
methods, respectively.
CREATE PROCEDURE FETCH_EX( IN a INT, INT b TABLE( c1 INT ) )
RESULT SET ( rc INT )
The example shows that prior to fetching/consuming from an input table, a table context must
be established via the open_result_set API on the a_v4_extfn_proc structure. The
open_result_set requires a table object, which can be obtained through the
get_value API.
an_extfn_value arg;
ctx->get_value( args_handle, 3, &arg );
After the table context is created, the rs structure executes the fetch_into API and fetches
the rows.
a_v4_extfn_row_block *rb = // get a row block to hold a series of
INT values.
rs->fetch_into( rs, &rb ) // fetch the rows.
Prior to producing rows to a result table, a table object must be created and returned to the
caller via the set_value API on the a_v4_extfn_proc_context structure.
This example shows that a table UDF must create an instance of the a_v4_extfn_table
structure. Each invocation of the table UDF should return a separate instance of the
a_v4_extfn_table structure. The table contains the state fields to keep track of the
current row and the number of rows to generate. State for a table can be stored as a field of the
instance.
typedef struct rg_table : a_v4_extfn_table {
a_sql_uint32 rows_to_generate;
a_sql_uint32 current_row;
} my_table;
In the following example, each time a row is produced, current_row is incremented until the
number of rows to be generated is reached, when fetch_into returns false to indicate end-
of-file. The consumer executes the fetch_into API implemented by the table UDF. As
part of the call to the fetch_into method, the consumer provides the table context, as well
as the row block to fetch into.
rs->fetch_into( rs, &rb )
return 0;
}
fetch_block
The fetch_block v4 API method fetches a block of rows.
Declaration
short fetch_block(
a_v4_extfn_table_context *cntxt,
a_v4_extfn_row_block **row_block)
Usage
The fetch_block method is used as an entry point when the consumer does not need the
data in a particular format. fetch_block requests that the producer create a data transfer
area and provide a pointer to that area. The consumer owns the memory and takes
responsibility for copying data from this area.
The fetch_block is more efficient if the consumer does not require a specific layout. The
fetch_block call sets a fetch_block to a block that can be consumed, and this block
should be passed on the next fetch_block call. This method is part of the
a_v4_extfn_table_context structure.
Programming 121
Using In-Database Analytics in Applications
Parameters
Parameter Description
cntxt The table context object.
When fetch_block is called and row_block points to NULL, the UDF must allocate a
a_v4_extfn_row_block structure.
Returns
1 if successful, 0 otherwise.
If the UDF returns 1, the consumer knows that there are more rows left and calls the
fetch_block method again. However, a UDF returning a value of 0 indicates that there are
no more rows and a call to the fetch_block method is unnecessary.
Consider the following procedure definition, which is an example of a TPF function that
consumes an input parameter table and produces it as a result table. Both are instances of SQL
values that are obtained and returned through the get_value and set_value v4 API
methods, respectively.
CREATE PROCEDURE FETCH_EX( IN a INT, INT b TABLE( c1 INT ) )
RESULT SET ( rc INT )
The example shows that prior to fetching/consuming from an input table, a table context must
be established via the open_result_set API on the a_v4_extfn_proc structure. The
open_result_set requires a table object, which can be obtained through the
get_value API.
an_extfn_value arg;
ctx->get_value( args_handle, 3, &arg );
After the table context is created, the rs structure executes the fetch_block API and
fetches the rows.
a_v4_extfn_row_block *rb = // get a row block to hold a series of
INT values.
rs->fetch_block( rs, &rb ) // fetch the rows.
Prior to producing rows to a result table, a table object must be created and returned to the
caller via the set_value API on the a_v4_extfn_proc_context structure.
This example shows that a table UDF must create an instance of the a_v4_extfn_table
structure. Each invocation of the table UDF should return a separate instance of the
a_v4_extfn_table structure. The table contains the state fields to keep track of the
current row and the number of rows to generate. State for a table can be stored as a field of the
instance.
typedef struct rg_table : a_v4_extfn_table {
a_sql_uint32 rows_to_generate;
a_sql_uint32 current_row;
} my_table;
rewind
Use the rewind v4 API method to restart a result set at the beginning of the table.
Declaration
short rewind(
a_v4_extfn_table_context *cntxt,
)
Usage
Call the rewind method on an open result set to rewind the table to the beginning. If the UDF
intends to rewind an input table, it must inform the producer during the state
EXTFNAPIV4_STATE_OPTIMIZATION using the
EXTFNAPIV4_DESCRIBE_PARM_TABLE_REQUEST_REWIND parameter.
rewind() is an optional entry point. If NULL, rewind is not supported. Otherwise, the
rewind() entry point restarts the result set at the beginning of the table.
Parameters
Parameter Description
cntxt The table context object
Programming 123
Using In-Database Analytics in Applications
Returns
1 if successful, 0 otherwise.
get_blob
Use the get_blob v4 API method to return a blob object from a specified column.
Declaration
short get_blob(
a_v4_extfn_table_context *cntxt,
a_v4_extfn_column_data *col,
a_v4_extfn_blob **blob
)
Usage
The blob is returned as an output parameter and is owned by the caller. Call this method only
on a column that contains a blob.
Use the helper macro EXTFN_COL_IS_BLOB to determine whether a column contains a
blob. This is the declaration of EXTFN_COL_IS_BLOB in the header file
extfnapiv4.h:
#define EXTFN_COL_IS_BLOB(c, n) (c[n].blob_handle != NULL)
Parameters
Parameter Description
cntxt The table context object
col The column data pointer for which to get the blob
Returns
1 if successful, 0 otherwise.
Implementation
typedef struct a_v4_extfn_table_func {
// size_t struct_size;
/* Open a result set. The UDF can allocate any resources needed
for the result set.
*/
short (UDF_CALLBACK *_open_extfn)(a_v4_extfn_table_context *);
/* Fetch rows into a provided row block. The UDF should implement
this method if it does
not have a preferred layout for its transfer area.
*/
short (UDF_CALLBACK *_fetch_into_extfn)(a_v4_extfn_table_context
*, a_v4_extfn_row_block
*row_block);
**row_block);
/* The following fields are reserved for future use and must be
initialized to NULL. */
void *_reserved1_must_be_null;
void *_reserved2_must_be_null;
} a_v4_extfn_table_func;
Method Summary
Method Data Type Description
_open_extfn void Called by the server to initiate row fetching by opening
a result set. The UDF can allocate any resources nee-
ded for the result set.
_fetch_in- short Fetch rows into a provided row block. The UDF im-
to_extfn plements this method, if it does not have a preferred
layout for its transfer area.
Programming 125
Using In-Database Analytics in Applications
Description
The a_v4_extfn_table_func structure defines the methods used to fetch results from a
table.
_open_extfn
The server calls the_open_extfn v4 API method to initiate fetching of rows.
Declaration
void _open_extfn(
a_v4_extfn_table_context *cntxt,
)
Usage
The UDF uses this method to open a result set and allocate any resources (for example,
streams) needed for sending results to the server.
Parameters
Parameter Description
cntxt The procedure context object
_fetch_into_extfn
The _fetch_into_extfn v4 API method fetches rows into a provided row block.
Declaration
short _fetch_into_extfn(
a_v4_extfn_table_context *cntxt,
a_v4_extfn_row_block *row_block
)
Usage
The UDF should implement this method, if it does not have a preferred layout for its transfer
area.
Parameters
Parameter Description
cntxt The procedure context object
Returns
1 if successful, 0 otherwise.
_fetch_block_extfn
The _fetch_block_extfn v4 API method fetches a block that is allocated and
configured by the UDF.
Declaration
short _fetch_block_extfn(
a_v4_extfn_table_context *cntxt,
a_v4_extfn_row_block **
)
Usage
The UDF should implement this method, if it has a preferred layout for its transfer area.
Parameters
Parameter Description
cntxt The procedure context object
Returns
1 if successful, 0 otherwise.
Programming 127
Using In-Database Analytics in Applications
_rewind_extfn
The _rewind_extfn v4 API method restarts a result set at the beginning of the table.
Declaration
void _rewind_extfn(
a_v4_extfn_table_context *cntxt,
)
Usage
This function is an optional entry point. The UDF implements the _rewind_extfn method
when the result table is rewound to the beginning. The UDF should consider implementing
this method only if it can provide the rewind functionality in an efficient and cost-effective
manner.
If a UDF chooses to implement the _rewind_extfn method, it should tell the consumer
during the state EXTFNAPIV4_STATE_OPTIMIZATION by setting the
EXTFNAPIV4_DESCRIBE_PARM_TABLE_HAS_REWIND parameter for argument 0.
The UDF may decide not to provide the rewind functionality, in which case the server
compensates and provides the functionality.
Note: The server can choose not to call the _rewind_extfn method to perform the rewind.
Parameters
Parameter Description
cntxt The procedure context object
Returns
No return value.
_close_extfn
The server calls the _close_extfn v4 API method to terminate fetching of rows.
Declaration
void _close_extfn(
a_v4_extfn_table_context *cntxt,
)
Usage
The UDF uses this method when fetching is complete to close a result set and release any
resources allocated for the result set.
Parameters
Parameter Description
cntxt The procedure context object
Programming 129
Using In-Database Analytics in Applications
Programming 131
Using SQL in Applications
Prepared statements
Each time a statement is sent to a database, the database server must perform the following
steps:
• It must parse the statement and transform it into an internal form. This process is
sometimes called preparing the statement.
• It must verify the correctness of all references to database objects by checking, for
example, that columns named in a query actually exist.
• If the statement involves joins or subqueries, then the query optimizer generates an access
plan.
• It executes the statement after all these steps have been carried out.
Programming 133
Using SQL in Applications
Cursor usage
When you execute a query in an application, the result set consists of several rows. In general,
you do not know how many rows the application is going to receive before you execute the
query. Cursors provide a way of handling query result sets in applications.
The way you use cursors and the kinds of cursors available to you depend on the programming
interface you use.
SAP Sybase IQ provides several system procedures to help determine what cursors are in use
for a connection, and what they contain:
With cursors, you can perform the following tasks within any programming interface:
• Loop over the results of a query.
• Perform inserts, updates, and deletes on the underlying data at any point within a result
set.
In addition, some programming interfaces allow you to use special features to tune the way
result sets return to your application, providing substantial performance benefits for your
application.
Cursors
A cursor is a name associated with a result set. The result set is obtained from a SELECT
statement or stored procedure call.
A cursor is a handle on the result set. At any time, the cursor has a well-defined position within
the result set. With a cursor you can examine and possibly manipulate the data one row at a
time. SAP Sybase IQ cursors support forward and backward movement through the query
results.
Cursor positions
Cursors can be positioned in the following places:
• Before the first row of the result set.
• On a row in the result set.
• After the last row of the result set.
Programming 135
Using SQL in Applications
The cursor position and result set are maintained in the database server. Rows are fetched by
the client for display and processing either one at a time or a few at a time. The entire result set
does not need to be delivered to the client.
Cursor principles
To use a cursor in ADO.NET, ODBC, JDBC, or Open Client, follow these general steps:
1. Prepare and execute a statement.
Execute a statement using the usual method for the interface. You can prepare and then
execute the statement, or you can execute the statement directly.
With ADO.NET, only the SACommand.ExecuteReader method returns a cursor. It
provides a read-only, forward-only cursor.
2. Test to see if the statement returns a result set.
A cursor is implicitly opened when a statement that creates a result set is executed. When
the cursor is opened, it is positioned before the first row of the result set.
3. Fetch results.
Although simple fetch operations move the cursor to the next row in the result set, SAP
Sybase IQ permits more complicated movement around the result set.
4. Close the cursor.
When you have finished with the cursor, close it to free associated resources.
5. Free the statement.
If you used a prepared statement, free it to reclaim memory.
The approach for using a cursor in embedded SQL differs from the approach used in other
interfaces. Follow these general steps to use a cursor in embedded SQL:
1. Prepare a statement.
Cursors generally use a statement handle rather than a string. You need to prepare a
statement to have a handle available.
2. Declare the cursor.
Each cursor refers to a single SELECT or CALL statement. When you declare a cursor,
you state the name of the cursor and the statement it refers to.
3. Open the cursor.
For a CALL statement, opening the cursor executes the procedure up to the point where the
first row is about to be obtained.
4. Fetch results.
Although simple fetch operations move the cursor to the next row in the result set, SAP
Sybase IQ permits more complicated movement around the result set. How you declare the
cursor determines which fetch operations are available to you.
5. Close the cursor.
When you have finished with the cursor, close it. This frees any resources associated with
the cursor.
6. Drop the statement.
To free the memory associated with the statement, you must drop the statement.
Programming 137
Using SQL in Applications
Cursor positioning
When a cursor is opened, it is positioned before the first row. You can move the cursor position
to an absolute position from the start or the end of the query results, or to a position relative to
the current cursor position. The specifics of how you change cursor position, and what
operations are possible, are governed by the programming interface.
The number of row positions you can fetch in a cursor is governed by the size of an integer. You
can fetch rows numbered up to number 2147483646, which is one less than the value that can
be held in an integer. When using negative numbers (rows from the end) you can fetch down to
one more than the largest negative value that can be held in an integer.
You can use special positioned update and delete operations to update or delete the row at the
current position of the cursor. If the cursor is positioned before the first row or after the last
row, an error is returned indicating that there is no corresponding cursor row.
Note: Inserts and some updates to asensitive cursors can cause problems with cursor
positioning. SAP Sybase IQ does not put inserted rows at a predictable position within a cursor
unless there is an ORDER BY clause on the SELECT statement. Sometimes the inserted row
does not appear at all until the cursor is closed and opened again. With SAP Sybase IQ, this
occurs if a work table had to be created to open the cursor.
The UPDATE statement may cause a row to move in the cursor. This happens if the cursor has
an ORDER BY clause that uses an existing index (a work table is not created). Using STATIC
SCROLL cursors alleviates these problems but requires more memory and processing.
Multiple-row fetching
Multiple-row fetching should not be confused with prefetching rows. Multiple row fetching is
performed by the application, while prefetching is transparent to the application, and provides
a similar performance gain. Fetching multiple rows at a time can improve performance.
Multiple-row fetches
Some interfaces provide methods for fetching more than one row at a time into the next several
fields in an array. Generally, the fewer separate fetch operations you execute, the fewer
individual requests the server must respond to, and the better the performance. A modified
FETCH statement that retrieves multiple rows is also sometimes called a wide fetch. Cursors
that use multiple-row fetches are sometimes called block cursors or fat cursors.
Scrollable cursors
ODBC and embedded SQL provide methods for using scrollable cursors and dynamic
scrollable cursors. These methods allow you to move several rows forward at a time, or to
move backward through the result set.
The JDBC and Open Client interfaces do not support scrollable cursors.
Prefetching does not apply to scrollable operations. For example, fetching a row in the reverse
direction does not prefetch several previous rows.
Programming 139
Using SQL in Applications
7. The positioned DELETE statement can be used on a cursor open on a view as long as the
view is updatable.
Updatable statements
This section describes how clauses in the SELECT statement affect updatable statements and
cursors.
Programming 141
Using SQL in Applications
Cursor types
This section describes mappings between SAP Sybase IQ cursors and the options available to
you from the programming interfaces supported by SAP Sybase IQ.
Availability of cursors
Not all interfaces provide support for all types of cursors.
• ADO.NET provides only forward-only, read-only cursors.
• ADO/OLE DB and ODBC support all types of cursors.
• Embedded SQL™ supports all types of cursors.
• For JDBC:
• The SQL Anywhere JDBC driver supports the JDBC 4.0 specification and permits the
declaration of insensitive, sensitive, and forward-only asensitive cursors.
• jConnect supports the declaration of insensitive, sensitive, and forward-only asensitive
cursors in the same manner as the SQL Anywhere JDBC driver. However, the
underlying implementation of jConnect only supports asensitive cursor semantics.
• Sybase Open Client supports only asensitive cursors. Also, a severe performance penalty
results when using updatable, non-unique cursors.
Cursor properties
You request a cursor type, either explicitly or implicitly, from the programming interface.
Different interface libraries offer different choices of cursor types. For example, JDBC and
ODBC specify different cursor types.
Each cursor type is defined by several characteristics:
• Uniqueness – Declaring a cursor to be unique forces the query to return all the columns
required to uniquely identify each row. Often this means returning all the columns in the
primary key. Any columns required but not specified are added to the result set. The default
cursor type is non-unique.
• Updatability – A cursor declared as read-only cannot be used in a positioned update or
delete operation. The default cursor type is updatable.
• Scrollability – You can declare cursors to behave different ways as you move through the
result set. Some cursors can fetch only the current row or the following row. Others can
move backward and forward through the result set.
• Sensitivity – Changes to the database may or may not be visible through a cursor.
These characteristics may have significant side effects on performance and on database server
memory usage.
SAP Sybase IQ makes available cursors with a variety of mixes of these characteristics. When
you request a cursor of a given type, SAP Sybase IQ tries to match those characteristics.
There are some occasions when not all characteristics can be supplied. For example,
insensitive cursors in SAP Sybase IQ must be read-only. If your application requests an
updatable insensitive cursor, a different cursor type (value-sensitive) is supplied instead.
Block cursors
ODBC provides a cursor type called a block cursor. When you use a BLOCK cursor, you can
use SQLFetchScroll or SQLExtendedFetch to fetch a block of rows, rather than a single row.
Block cursors behave identically to embedded SQL ARRAY fetches.
Programming 143
Using SQL in Applications
2 Cobb
3 Chin
A cursor on the following query returns all results from the table in primary key order:
SELECT EmployeeID, Surname
FROM Employees
ORDER BY EmployeeID;
The membership of the result set could be changed by adding a new row or deleting a row. The
values could be changed by changing one of the names in the table. The order could be
changed by changing the primary key value of one of the employees.
• Value-sensitive cursors – Changes to the order or values of the underlying data are
visible. The membership of the result set is fixed when the cursor is opened.
The differing requirements on cursors place different constraints on execution and therefore
affect performance.
EmployeeID Surname
102 Whitney
105 Cobb
160 Breault
... ...
2. The application fetches the first row through the cursor (102).
3. The application fetches the next row through the cursor (105).
4. A separate transaction deletes employee 102 (Whitney) and commits the change.
The results of cursor actions in this situation depend on the cursor sensitivity:
• Insensitive cursors – The DELETE is not reflected in either the membership or values of
the results as seen through the cursor:
Action Result
Fetch previous row Returns the original copy of the row (102).
Fetch the first row (absolute fetch) Returns the original copy of the row (102).
Fetch the second row (absolute fetch) Returns the unchanged row (105).
• Sensitive cursors – The membership of the result set has changed so that row 105 is now
the first row in the result set:
Action Result
Fetch previous row Returns Row Not Found. There is no pre-
vious row.
Programming 145
Using SQL in Applications
Action Result
Fetch the first row (absolute fetch) Returns row 105.
Fetch the first row (absolute fetch) Returns No current row of cur-
sor. There is a hole in the cursor where the
first row used to be.
EmployeeID Surname
102 Whitney
105 Cobb
160 Breault
EmployeeID Surname
... ...
2. The application fetches the first row through the cursor (102).
3. The application fetches the next row through the cursor (105).
4. A separate transaction updates the employee ID of employee 102 (Whitney) to 165 and
commits the change.
The results of the cursor actions in this situation depend on the cursor sensitivity:
• Insensitive cursors – The UPDATE is not reflected in either the membership or values of
the results as seen through the cursor:
Action Result
Fetch previous row Returns the original copy of the row (102).
Fetch the first row (absolute fetch) Returns the original copy of the row (102).
Fetch the second row (absolute fetch) Returns the unchanged row (105).
• Sensitive cursors – The membership of the result set has changed so that row 105 is now
the first row in the result set:
Action Result
Fetch previous row Returns SQLCODE 100. The membership of
the result set has changed so that 105 is now the
first row. The cursor is moved to the position
before the first row.
Programming 147
Using SQL in Applications
Action Result
Fetch previous row Returns SQLCODE 100. The membership of
the result set has changed so that 105 is now the
first row: The cursor is positioned on the hole: it
is before row 105.
Fetch the first row (absolute fetch) Returns SQLCODE -197. The membership of
the result set has changed so that 105 is now the
first row: The cursor is positioned on the hole: it
is before row 105.
Note: Update warning and error conditions do not occur in bulk operations mode (-b database
server option).
Standards
Insensitive cursors correspond to the ISO/ANSI standard definition of insensitive cursors, and
to ODBC static cursors.
Programming interfaces
Interface Cursor type Comment
ODBC, ADO/OLE DB Static If an updatable static cursor is
requested, a value-sensitive cur-
sor is used instead.
Description
Insensitive cursors always return rows that match the query's selection criteria, in the order
specified by any ORDER BY clause.
The result set of an insensitive cursor is fully materialized as a work table when the cursor is
opened. This has the following consequences:
• If the result set is very large, the disk space and memory requirements for managing the
result set may be significant.
• No row is returned to the application before the entire result set is assembled as a work
table. For complex queries, this may lead to a delay before the first row is returned to the
application.
• Subsequent rows can be fetched directly from the work table, and so are returned quickly.
The client library may prefetch several rows at a time, further improving performance.
• Insensitive cursors are not affected by ROLLBACK or ROLLBACK TO SAVEPOINT.
Standards
Sensitive cursors correspond to the ISO/ANSI standard definition of sensitive cursors, and to
ODBC dynamic cursors.
Programming interfaces
Interface Cursor type Comment
ODBC, ADO/OLE DB Dynamic
Description
Prefetching is disabled for sensitive cursors. All changes are visible through the cursor,
including changes through the cursor and from other transactions. Higher isolation levels may
hide some changes made in other transactions because of locking.
Programming 149
Using SQL in Applications
Changes to cursor membership, order, and all column values are all visible. For example, if a
sensitive cursor contains a join, and one of the values of one of the underlying tables is
modified, then all result rows composed from that base row show the new value. Result set
membership and order may change at each fetch.
Sensitive cursors always return rows that match the query's selection criteria, and are in the
order specified by any ORDER BY clause. Updates may affect the membership, order, and
values of the result set.
The requirements of sensitive cursors place restrictions on the implementation of sensitive
cursors:
• Rows cannot be prefetched, as changes to the prefetched rows would not be visible through
the cursor. This may impact performance.
• Sensitive cursors must be implemented without any work tables being constructed, as
changes to those rows stored as work tables would not be visible through the cursor.
• The no work table limitation restricts the choice of join method by the optimizer and
therefore may impact performance.
• For some queries, the optimizer is unable to construct a plan that does not include a work
table that would make a cursor sensitive.
Work tables are commonly used for sorting and grouping intermediate results. A work
table is not needed for sorting if the rows can be accessed through an index. It is not
possible to state exactly which queries employ work tables, but the following queries do
employ them:
• UNION queries, although UNION ALL queries do not necessarily use work tables.
• Statements with an ORDER BY clause, if there is no index on the ORDER BY column.
• Any query that is optimized using a hash join.
• Many queries involving DISTINCT or GROUP BY clauses.
In these cases, SAP Sybase IQ either returns an error to the application, or changes the
cursor type to an asensitive cursor and returns a warning.
Standards
Asensitive cursors correspond to the ISO/ANSI standard definition of asensitive cursors, and
to ODBC cursors with unspecific sensitivity.
Programming interfaces
Interface Cursor type
ODBC, ADO/OLE DB Unspecified sensitivity
Description
A request for an asensitive cursor places few restrictions on the methods SAP Sybase IQ can
use to optimize the query and return rows to the application. For these reasons, asensitive
cursors provide the best performance. In particular, the optimizer is free to employ any
measure of materialization of intermediate results as work tables, and rows can be prefetched
by the client.
SAP Sybase IQ makes no guarantees about the visibility of changes to base underlying rows.
Some changes may be visible, others not. Membership and order may change at each fetch. In
particular, updates to base rows may result in only some of the updated columns being
reflected in the cursor's result.
Asensitive cursors do not guarantee to return rows that match the query's selection and order.
The row membership is fixed at cursor open time, but subsequent changes to the underlying
values are reflected in the results.
Asensitive cursors always return rows that matched the customer's WHERE and ORDER BY
clauses at the time the cursor membership is established. If column values change after the
cursor is opened, rows may be returned that no longer match WHERE and ORDER BY
clauses.
Standards
Value-sensitive cursors do not correspond to an ISO/ANSI standard definition. They
correspond to ODBC keyset-driven cursors.
Programming interfaces
Interface Cursor type Comment
ODBC, ADO/OLE DB Keyset-driven
Programming 151
Using SQL in Applications
Description
If the application fetches a row composed of a base underlying row that has changed, then the
application must be presented with the updated value, and the SQL_ROW_UPDATED status
must be issued to the application. If the application attempts to fetch a row that was composed
of a base underlying row that was deleted, a SQL_ROW_DELETED status must be issued to
the application.
Changes to primary key values remove the row from the result set (treated as a delete, followed
by an insert). A special case occurs when a row in the result set is deleted (either from cursor or
outside) and a new row with the same key value is inserted. This will result in the new row
replacing the old row where it appeared.
There is no guarantee that rows in the result set match the query's selection or order
specification. Since row membership is fixed at open time, subsequent changes that make a
row not match the WHERE clause or ORDER BY do not change a row's membership nor
position.
All values are sensitive to changes made through the cursor. The sensitivity of membership to
changes made through the cursor is controlled by the ODBC option
SQL_STATIC_SENSITIVITY. If this option is on, then inserts through the cursor add the row
to the cursor. Otherwise, they are not part of the result set. Deletes through the cursor remove
the row from the result set, preventing a hole returning the SQL_ROW_DELETED status.
Value-sensitive cursors use a key set table. When the cursor is opened, SAP Sybase IQ
populates a work table with identifying information for each row contributing to the result set.
When scrolling through the result set, the key set table is used to identify the membership of
the result set, but values are obtained, if necessary, from the underlying tables.
The fixed membership property of value-sensitive cursors allows your application to
remember row positions within a cursor and be assured that these positions will not change.
• If a row was updated or may have been updated since the cursor was opened, SAP Sybase
IQ returns a SQLE_ROW_UPDATED_WARNING when the row is fetched. The warning
is generated only once: fetching the same row again does not produce the warning.
An update to any column of the row causes the warning, even if the updated column is not
referenced by the cursor. For example, a cursor on Surname and GivenName would report
the update even if only the Birthdate column was modified. These update warning and
error conditions do not occur in bulk operations mode (-b database server option) when
row locking is disabled.
• An attempt to execute a positioned update or delete on a row that has been modified since it
was last fetched returns a SQLE_ROW_UPDATED_SINCE_READ error and cancels the
statement. An application must FETCH the row again before the UPDATE or DELETE is
permitted.
An update to any column of the row causes the error, even if the updated column is not
referenced by the cursor. The error does not occur in bulk operations mode.
• If a row has been deleted after the cursor is opened, either through the cursor or from
another transaction, a hole is created in the cursor. The membership of the cursor is fixed,
so a row position is reserved, but the DELETE operation is reflected in the changed value
of the row. If you fetch the row at this hole, you receive a -197 SQLCODE error, indicating
that there is no current row, and the cursor is left positioned on the hole. You can avoid
holes by using sensitive cursors, as their membership changes along with the values.
Rows cannot be prefetched for value-sensitive cursors. This requirement may affect
performance.
Programming 153
Using SQL in Applications
Prefetches
Prefetches and multiple-row fetches are different. Prefetches can be carried out without
explicit instructions from the client application. Prefetching retrieves rows from the server
into a buffer on the client side, but does not make those rows available to the client application
until the application fetches the appropriate row.
By default, the SAP Sybase IQ client library prefetches multiple rows whenever an
application fetches a single row. The SAP Sybase IQ client library stores the additional rows in
a buffer.
Prefetching assists performance by cutting down on client/server round trips, and increases
throughput by making many rows available without a separate request to the server for each
row or block of rows.
Lost updates
When using an updatable cursor, it is important to guard against lost updates. A lost update is a
scenario in which two or more transactions update the same row, but neither transaction is
aware of the modification made by the other transaction, and the second change overwrites the
first modification. The following example illustrates this problem:
1. An application opens a cursor on the following query against the sample database.
SELECT ID, Quantity
FROM Products;
ID Quantity
300 28
301 54
302 75
... ...
2. The application fetches the row with ID = 300 through the cursor.
3. A separate transaction updates the row using the following statement:
UPDATE Products
SET Quantity = Quantity - 10
WHERE ID = 300;
4. The application then updates the row through the cursor to a value of (Quantity -
5).
5. The correct final value for the row would be 13. If the cursor had prefetched the row, the
new value of the row would be 23. The update from the separate transaction is lost.
In a database application, the potential for a lost update exists at any isolation level if changes
are made to rows without verification of their values beforehand. At higher isolation levels (2
and 3), locking (read, intent, and write locks) can be used to ensure that changes to rows cannot
be made by another transaction once the row has been read by the application. However, at
isolation levels 0 and 1, the potential for lost updates is greater: at isolation level 0, read locks
are not acquired to prevent subsequent changes to the data, and isolation level 1 only locks the
current row. Lost updates cannot occur when using snapshot isolation since any attempt to
Programming 155
Using SQL in Applications
change an old value results in an update conflict. Also, the use of prefetching at isolation level
1 can also introduce the potential for lost updates, since the result set row that the application is
positioned on, which is in the client's prefetch buffer, may not be the same as the current row
that the server is positioned on in the cursor.
To prevent lost updates from occurring with cursors at isolation level 1, the database server
supports three different concurrency control mechanisms that can be specified by an
application:
1. The acquisition of intent row locks on each row in the cursor as it is fetched. Intent locks
prevent other transactions from acquiring intent or write locks on the same row, preventing
simultaneous updates. However, intent locks do not block read row locks, so they do not
affect the concurrency of read-only statements.
2. The use of a value-sensitive cursor. Value-sensitive cursors can be used to track when an
underlying row has changed, or has been deleted, so that the application can respond.
3. The use of FETCH FOR UPDATE, which acquires an intent row lock for that specific
row.
How these alternatives are specified depends on the interface used by the application. For the
first two alternatives that pertain to a SELECT statement:
• In ODBC, lost updates cannot occur because the application must specify a cursor
concurrency parameter to the SQLSetStmtAttr function when declaring an updatable
cursor. This parameter is one of SQL_CONCUR_LOCK, SQL_CONCUR_VALUES,
SQL_CONCUR_READ_ONLY, or SQL_CONCUR_TIMESTAMP. For
SQL_CONCUR_LOCK, the database server acquires row intent locks. For
SQL_CONCUR_VALUES and SQL_CONCUR_TIMESTAMP, a value-sensitive cursor
is used. SQL_CONCUR_READ_ONLY is used for read-only cursors, and is the default.
• In JDBC, the concurrency setting for a statement is similar to that of ODBC. The SQL
Anywhere JDBC driver supports the JDBC concurrency values
RESULTSET_CONCUR_READ_ONLY and RESULTSET_CONCUR_UPDATABLE.
The first value corresponds to the ODBC concurrency setting
SQL_CONCUR_READ_ONLY and specifies a read-only statement. The second value
corresponds to the ODBC SQL_CONCUR_LOCK setting, so row intent locks are used to
prevent lost updates. Value-sensitive cursors cannot be specified directly in the JDBC 4.0
specification.
• In jConnect, updatable cursors are supported at the API level, but the underlying
implementation (using TDS) does not support updates through a cursor. Instead, jConnect
sends a separate UPDATE statement to the database server to update the specific row. To
avoid lost updates, the application must run at isolation level 2 or higher. Alternatively, the
application can issue separate UPDATE statements from the cursor, but you must ensure
that the UPDATE statement verifies that the row values have not been altered since the row
was read by placing appropriate conditions in the UPDATE statement's WHERE clause.
• In embedded SQL, a concurrency specification can be set by including syntax within the
SELECT statement itself, or in the cursor declaration. In the SELECT statement, the
syntax SELECT...FOR UPDATE BY LOCK causes the database server to acquire intent
row locks on the result set.
Alternatively, SELECT...FOR UPDATE BY [ VALUES | TIMESTAMP ] causes the
database server to change the cursor type to a value-sensitive cursor, so that if a specific
row has been changed since the row was last read through the cursor, the application
receives either a warning (SQLE_ROW_UPDATED_WARNING) on a FETCH
statement, or an error (SQLE_ROW_UPDATED_SINCE_READ) on an UPDATE
WHERE CURRENT OF statement. If the row was deleted, the application also receives an
error (SQLE_NO_CURRENT_ROW).
FETCH FOR UPDATE functionality is also supported by the embedded SQL and ODBC
interfaces, although the details differ depending on the API that is used.
In embedded SQL, the application uses FETCH FOR UPDATE, rather than FETCH, to cause
an intent lock to be acquired on the row. In ODBC, the application uses the API call
SQLSetPos with the operation argument SQL_POSITION or SQL_REFRESH, and the lock
type argument SQL_LOCK_EXCLUSIVE, to acquire an intent lock on a row. In SAP Sybase
IQ, these are long-term locks that are held until the transaction commits or rolls back.
Programming 157
Using SQL in Applications
combination of cursor sensitivity and isolation level that controls the various concurrency
scenarios that are possible with a particular application.
ADO.NET
Forward-only, read-only cursors are available by using SACommand.ExecuteReader. The
SADataAdapter object uses a client-side result set instead of cursors.
Exceptions
If a STATIC cursor is requested as updatable, a value-sensitive cursor is supplied instead and a
warning is issued.
If a DYNAMIC or MIXED cursor is requested and the query cannot be executed without using
work tables, a warning is issued and an asensitive cursor is supplied instead.
JDBC
The JDBC 4.0 specification supports three types of cursors: insensitive, sensitive, and
forward-only asensitive. The SQL Anywhere JDBC driver is compliant with these JDBC
specifications and supports these different cursor types for a JDBC ResultSet object.
However, there are cases when the database server cannot construct an access plan with the
required semantics for a given cursor type. In these cases, the database server either returns an
error or substitutes a different cursor type.
With jConnect, the underlying protocol (TDS) only supports forward-only, read-only
asensitive cursors on the database server, even though jConnect supports the APIs for creating
different types of cursors following the JDBC 2.0 specification. All jConnect cursors are
asensitive because the TDS protocol buffers the statement's result set in blocks. These blocks
of buffered results are scrolled when the application needs to scroll through an insensitive or
sensitive cursor type that supports scrollability. If the application scrolls backward past the
beginning of the cached result set, the statement is re-executed, which can result in data
inconsistencies if the data has been altered between statement executions.
Embedded SQL
To request a cursor from an embedded SQL application, you specify the cursor type on the
DECLARE statement. The following table illustrates the cursor sensitivity that is set in
response to different requests:
Cursor type SAP Sybase IQ cursor
NO SCROLL Asensitive
DYNAMIC SCROLL Asensitive
SCROLL Value-sensitive
INSENSITIVE Insensitive
SENSITIVE Sensitive
Exceptions
If a DYNAMIC SCROLL or NO SCROLL cursor is requested as UPDATABLE, then a
sensitive or value-sensitive cursor is supplied. It is not guaranteed which of the two is supplied.
This uncertainty fits the definition of asensitive behavior.
If an INSENSITIVE cursor is requested as UPDATABLE, then a value-sensitive cursor is
supplied.
If a DYNAMIC SCROLL cursor is requested, if the prefetch database option is set to Off, and
if the query execution plan involves no work tables, then a sensitive cursor may be supplied.
Again, this uncertainty fits the definition of asensitive behavior.
Open Client
As with jConnect, the underlying protocol (TDS) for Open Client only supports forward-only,
read-only, asensitive cursors.
Programming 159
Using SQL in Applications
Implementation notes
• In embedded SQL, a SQLDA (SQL Descriptor Area) structure holds the descriptor
information.
• In ODBC, a descriptor handle allocated using SQLAllocHandle provides access to the
fields of a descriptor. You can manipulate these fields using SQLSetDescRec,
SQLSetDescField, SQLGetDescRec, and SQLGetDescField.
Alternatively, you can use SQLDescribeCol and SQLColAttributes to obtain column
information.
• In Open Client, you can use ct_dynamic to prepare a statement and ct_describe to describe
the result set of the statement. However, you can also use ct_command to send a SQL
statement without preparing it first and use ct_results to handle the returned rows one by
one. This is the more common way of operating in Open Client application development.
• In JDBC, the java.sql.ResultSetMetaData class provides information about result sets.
• You can also use descriptors for sending data to the database server (for example, with the
INSERT statement); however, this is a different kind of descriptor than for result sets.
Transactions in applications
Transactions are sets of atomic SQL statements. Either all statements in the transaction are
executed, or none. This section describes a few aspects of transactions in applications.
Programming 161
Using SQL in Applications
If you are using an interface that controls commits on the client side, setting the chained
database option (a server-side option) can impact performance and/or behavior of your
application. Setting the server's chained mode is not recommended.
Programming 163
Using SQL in Applications
The draft ISO SQL3 standard states that on a rollback, all cursors (even those cursors opened
WITH HOLD) should close. You can obtain this behavior by setting the
ansi_close_cursors_on_rollback option to On.
Savepoints
If a transaction rolls back to a savepoint, and if the ansi_close_cursors_on_rollback option is
On, then all cursors (even those cursors opened WITH HOLD) opened after the SAVEPOINT
close.
ADO.NET applications
You can develop Internet and intranet applications using object-oriented languages, and then
connect these applications to SAP Sybase IQ using the ADO.NET data provider.
Combine this provider with built-in XML and web services features, .NET scripting
capability for MobiLink™ synchronization, and an UltraLite.NET™ component for
development of handheld database applications, and SAP Sybase IQ can integrate with
the .NET Framework.
Programming 165
.NET Application Programming
Prerequisites
There are no prerequisites for this task.
Task
Programming 167
.NET Application Programming
The reference indicates which provider to include and locates the code for the SAP Sybase
IQ .NET Data Provider.
3. Click the .NET tab, and scroll through the list to locate any of the following:
iAnywhere.Data.SQLAnywhere for .NET 2
iAnywhere.Data.SQLAnywhere for .NET 3.5
iAnywhere.Data.SQLAnywhere for .NET 4
4. Click the desired provider and then click OK.
The provider is added to the References folder in the Solution Explorer window of your
project.
5. Specify a directive to your source code to assist with the use of the SAP Sybase IQ .NET
Data Provider namespace and the defined types.
Add the following line to your project:
• If you are using C#, add the following line to the list of using directives at the
beginning of your source code:
using iAnywhere.Data.SQLAnywhere;
• If you are using Visual Basic, add the following line at the beginning of source code:
Imports iAnywhere.Data.SQLAnywhere
The SAP Sybase IQ .NET Data Provider is set up for use with your .NET application.
C# SAConnection example
The following C# code creates a button click handler that opens a connection to the SAP
Sybase IQ sample database and then closes it. An exception handler is included.
private void button1_Click(object sender, EventArgs e)
{
SAConnection conn = new SAConnection("Data Source=Sybase IQ
Demo");
try
{
conn.Open();
conn.Close();
}
conn.Close()
Catch ex As SAException
MessageBox.Show(ex.Errors(0).Source & " : " & _
ex.Errors(0).Message & " (" & _
ex.Errors(0).NativeError.ToString() & ")", _
"Failed to connect")
End Try
End Sub
Connection Pooling
The SAP Sybase IQ .NET Data Provider supports native .NET connection pooling.
Connection pooling allows your application to reuse existing connections by saving the
connection handle to a pool so it can be reused, rather than repeatedly creating a new
connection to the database. Connection pooling is enabled by default.
Connection pooling is enabled and disabled using the Pooling option. The maximum pool
size is set in your connection string using the Max Pool Size option. The minimum or
initial pool size is set in your connection string using the Min Pool Size option. The
default maximum pool size is 100, while the default minimum pool size is 0.
"Data Source=Sybase IQ Demo;Pooling=true;Max Pool Size=50;Min Pool
Size=5"
When your application first attempts to connect to the database, it checks the pool for an
existing connection that uses the same connection parameters you have specified. If a
matching connection is found, that connection is used. Otherwise, a new connection is used.
When you disconnect, the connection is returned to the pool so that it can be reused.
The SAP Sybase IQ database server also supports connection pooling. This feature is
controlled using the ConnectionPool (CPOOL) connection parameter. However, the SAP
Sybase IQ .NET Data Provider does not use this server feature and disables it (CPOOL=NO).
All connection pooling is done in the .NET client application instead (client-side connection
pooling).
Programming 169
.NET Application Programming
Connection State
Once your application has established a connection to the database, you can check the
connection state to ensure that the connection is still open before communicating a request to
the database server. If a connection is closed, you can return an appropriate message to the user
and/or attempt to reopen the connection.
The SAConnection class has a State property that can be used to check the state of the
connection. Possible state values are ConnectionState.Open and ConnectionState.Closed.
The following code checks whether the SAConnection object has been initialized, and if it has,
it checks that the connection is open. A message is returned to the user if the connection is not
open.
if ( conn == null || conn.State != ConnectionState.Open )
{
MessageBox.Show( "Connect to a database first", "Not
connected" );
return;
}
C# ExecuteReader Example
The following C# code opens a connection to the SAP Sybase IQ sample database and uses the
ExecuteReader method to create a result set containing the last names of employees in the
Employees table:
SAConnection conn = new SAConnection("Data Source=Sybase IQ Demo");
conn.Open();
SACommand cmd = new SACommand("SELECT Surname FROM Employees", conn);
SADataReader reader = cmd.ExecuteReader();
listEmployees.BeginUpdate();
while (reader.Read())
{
listEmployees.Items.Add(reader.GetString(0));
}
listEmployees.EndUpdate();
reader.Close();
conn.Close();
Programming 171
.NET Application Programming
ListEmployees.EndUpdate()
conn.Close()
C# ExecuteScalar Example
The following C# code opens a connection to the SAP Sybase IQ sample database and uses the
ExecuteScalar method to obtain a count of the number of male employees in the Employees
table:
SAConnection conn = new SAConnection("Data Source=Sybase IQ Demo");
conn.Open();
SACommand cmd = new SACommand(
"SELECT COUNT(*) FROM Employees WHERE Sex = 'M'", conn );
int count = (int) cmd.ExecuteScalar();
textBox1.Text = count.ToString();
conn.Close();
insertCmd.Parameters[0].Value = 600;
insertCmd.Parameters[1].Value = "Eastern Sales";
int recordsAffected = insertCmd.ExecuteNonQuery();
insertCmd.Parameters[0].Value = 700;
insertCmd.Parameters[1].Value = "Western Sales";
recordsAffected = insertCmd.ExecuteNonQuery();
System.Windows.Forms.DataGrid dataGrid;
dataGrid = new System.Windows.Forms.DataGrid();
dataGrid.Location = new Point(15, 50);
dataGrid.Size = new Size(275, 200);
dataGrid.CaptionText = "SACommand Example";
this.Controls.Add(dataGrid);
dataGrid.DataSource = dr;
dr.Close();
conn.Close();
Programming 173
.NET Application Programming
rows of the Departments table where the DepartmentID is 100. It displays the updated table in
a datagrid.
SAConnection conn = new SAConnection("Data Source=Sybase IQ Demo");
conn.Open();
System.Windows.Forms.DataGrid dataGrid;
dataGrid = new System.Windows.Forms.DataGrid();
dataGrid.Location = new Point(15, 50);
dataGrid.Size = new Size(275, 200);
dataGrid.CaptionText = "SACommand Example";
this.Controls.Add(dataGrid);
dataGrid.DataSource = dr;
dr.Close();
conn.Close();
sp_adodotnet_primarykey(" +
"out p_id int, in p_name char(40) )" +
"BEGIN " +
"INSERT INTO adodotnet_primarykey( name ) VALUES( p_name );" +
"SELECT @@IDENTITY INTO p_id;" +
"END";
cmd.ExecuteNonQuery();
cmd.CommandText = "sp_adodotnet_primarykey";
cmd.CommandType = CommandType.StoredProcedure;
SADataAdapter: Overview
The SADataAdapter retrieves a result set into a DataTable. A DataSet is a collection of tables
(DataTables) and the relationships and constraints between those tables. The DataSet is built
Programming 175
.NET Application Programming
into the .NET Framework, and is independent of the Data Provider used to connect to your
database.
When you use the SADataAdapter, you must be connected to the database to fill a DataTable
and to update the database with changes made to the DataTable. However, once the DataTable
is filled, you can modify the DataTable while disconnected from the database.
If you do not want to apply your changes to the database right away, you can write the DataSet,
including the data and/or the schema, to an XML file using the WriteXml method. Then, you
can apply the changes at a later time by loading a DataSet with the ReadXml method. The
following shows two examples.
ds.WriteXml("Employees.xml");
ds.WriteXml("EmployeesWithSchema.xml", XmlWriteMode.WriteSchema);
For more information, see the .NET Framework documentation for WriteXml and ReadXml.
When you call the Update method to apply changes from the DataSet to the database, the
SADataAdapter analyzes the changes that have been made and then invokes the appropriate
statements, INSERT, UPDATE, or DELETE, as necessary. When you use the DataSet, you
can only make changes (inserts, updates, or deletes) to data that is from a single table. You
cannot update result sets that are based on joins. If another user has a lock on the row you are
trying to update, an exception is thrown.
Warning! Any changes you make to the DataSet are made while you are disconnected. Your
application does not have locks on these rows in the database. Your application must be
designed to resolve any conflicts that may occur when changes from the DataSet are applied to
the database if another user changes the data you are modifying before your changes are
applied to the database.
recommended because it allows you to set the isolation level for the transaction and it places
locks on the rows so that other users cannot modify them.
To simplify the process of conflict resolution, you can design your INSERT, UPDATE, or
DELETE statement to be a stored procedure call. By including INSERT, UPDATE, and
DELETE statements in stored procedures, you can catch the error if the operation fails. In
addition to the statement, you can add error handling logic to the stored procedure so that if the
operation fails the appropriate action is taken, such as recording the error to a log file, or trying
the operation again.
Programming 177
.NET Application Programming
used to create a DataTable table named Results in the DataSet and then fill it with the results of
the query. The Results DataTable is then bound to the grid on the screen.
SAConnection conn = new SAConnection( "Data Source=Sybase IQ Demo" );
conn.Open();
DataSet ds = new DataSet();
SADataAdapter da = new SADataAdapter("SELECT * FROM Employees",
conn);
da.Fill(ds, "Results");
conn.Close();
dataGridView1.DataSource = ds.Tables["Results"];
Programming 179
.NET Application Programming
dataTable.Clear();
rowCount = da.Fill( dataTable );
conn.Close();
dataGridView1.DataSource = dataTable;
rowCount = da.Update(dataTable);
dataTable.Clear();
rowCount = da.Fill(dataTable);
conn.Close();
dataGridView1.DataSource = dataTable;
Programming 181
.NET Application Programming
dataTable.Clear();
rowCount = da.Fill( dataTable );
conn.Close();
dataGridView1.DataSource = dataTable;
row = dataTable.NewRow();
row[0] = -2;
row[1] = "Marketing --- Adapter";
dataTable.Rows.Add(row);
row = dataTable.NewRow();
row[0] = -3;
row[1] = "Sales --- Adapter";
dataTable.Rows.Add(row);
row = dataTable.NewRow();
row[0] = -4;
row[1] = "Shipping --- Adapter";
dataTable.Rows.Add(row);
conn.Close();
dataGridView1.DataSource = ds.Tables["Departments"];
Programming 183
.NET Application Programming
BLOBs
When fetching long string values or binary data, there are methods that you can use to fetch the
data in pieces. For binary data, use the GetBytes method, and for string data, use the GetChars
method. Otherwise, BLOB data is treated in the same manner as any other data you fetch from
the database.
int idValue;
int productIdValue;
int length = 100;
char[] buf = new char[length];
while (reader.Read())
{
idValue = reader.GetInt32(0);
productIdValue = reader.GetInt32(1);
long blobLength = 0;
long charsRead;
while ((charsRead = reader.GetChars(2, blobLength, buf, 0,
length))
== (long)length)
{
blobLength += charsRead;
}
blobLength += charsRead;
}
reader.Close();
conn.Close();
Time Values
The .NET Framework does not have a Time structure. To fetch time values from SAP Sybase
IQ, you must use the GetTimeSpan method. This method returns the data as a .NET
Framework TimeSpan object.
C# TimeSpan Example
The following example uses the GetTimeSpan method to return the time as TimeSpan.
SAConnection conn = new SAConnection( "Data Source=Sybase IQ Demo" );
conn.Open();
SACommand cmd = new SACommand("SELECT 123, CURRENT TIME", conn);
SADataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
int ID = reader.GetInt32(0);
TimeSpan time = reader.GetTimeSpan(1);
}
reader.Close();
conn.Close();
Stored Procedures
You can use SQL stored procedures with the SAP Sybase IQ .NET Data Provider.
The ExecuteReader method is used to call stored procedures that return result sets, while the
ExecuteNonQuery method is used to call stored procedures that do not return any result sets.
The ExecuteScalar method is used to call stored procedures that return only a single value.
You can use SAParameter objects to pass parameters to a stored procedure.
listBox1.BeginUpdate();
listBox1.Items.Add("Name=" + name +
" Description=" + description + " Price=" + price);
listBox1.EndUpdate();
Programming 185
.NET Application Programming
conn.Close();
Transaction Processing
With the SAP Sybase IQ .NET Data Provider, you can use the SATransaction object to group
statements together. Each transaction ends with a COMMIT or ROLLBACK, which either
makes your changes to the database permanent or cancels all the operations in the transaction.
Once the transaction is complete, you must create a new SATransaction object to make further
changes. This behavior is different from ODBC and embedded SQL, where a transaction
persists after you execute a COMMIT or ROLLBACK until the transaction is closed.
If you do not create a transaction, the SAP Sybase IQ .NET Data Provider operates in
autocommit mode by default. There is an implicit COMMIT after each insert, update, or
delete, and once an operation is completed, the change is made to the database. In this case, the
changes cannot be rolled back.
C# SATransaction Example
The following example shows how to wrap an INSERT into a transaction so that it can be
committed or rolled back. A transaction is created with an SATransaction object and linked to
the execution of a SQL statement using an SACommand object. Isolation level 2
(RepeatableRead) is specified so that other database users cannot update the row. The lock on
the row is released when the transaction is committed or rolled back. If you do not use a
transaction, the SAP Sybase IQ .NET Data Provider operates in autocommit mode and you
cannot roll back any changes that you make to the database.
SATransaction trans =
conn.BeginTransaction(SAIsolationLevel.RepeatableRead);
SACommand cmd = new SACommand(stmt, conn, trans);
int rowsAffected = cmd.ExecuteNonQuery();
if (goAhead)
trans.Commit();
else
trans.Rollback();
conn.Close();
Error handling
Your application should be designed to handle any errors that occur.
The SAP Sybase IQ .NET Data Provider creates an SAException object and throws an
exception whenever errors occur during execution. Each SAException object consists of a list
of SAError objects, and these error objects include the error message and code.
Errors are different from conflicts. Conflicts arise when changes are applied to the database.
Your application should include a process to compute correct values or to log conflicts when
they arise.
Programming 187
.NET Application Programming
namespace CodeFirstExample
{
[Table( "EdmCategories", Schema = "DBA" )]
public class Category
{
public string CategoryID { get; set; }
[MaxLength( 64 )]
public string Name { get; set; }
class Program
{
static void Main( string[] args )
{
Database.DefaultConnectionFactory = new
SAConnectionFactory();
Database.SetInitializer<Context>( new
DropCreateDatabaseAlways<Context>() );
To build and run this example, the following assembly references must be added:
Programming 189
.NET Application Programming
EntityFramework
iAnywhere.Data.SQLAnywhere.v4.0
System.ComponentModel.DataAnnotations
System.Data.Entity
namespace CodeFirstExample
{
[Table( "Customers", Schema = "GROUPO" )]
public class Customer
{
[Key()]
public int ID { get; set; }
public string SurName { get; set; }
public string GivenName { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Country { get; set; }
public string PostalCode { get; set; }
public string Phone { get; set; }
public string CompanyName { get; set; }
[ForeignKey( "Customer" )]
public int CustomerID { get; set; }
public virtual Customer Customer { get; set; }
}
class Program
{
static void Main( string[] args )
{
Database.DefaultConnectionFactory = new
SAConnectionFactory();
Database.SetInitializer<Context>( null );
There are some implementation detail differences between the Microsoft .NET Framework
Data Provider for SQL Server (SqlClient) and the SAP Sybase IQ .NET Data Provider of
which you should be aware.
Programming 191
.NET Application Programming
{
[Key()]
public int ID { get; set; }
public string SurName { get; set; }
public string GivenName { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Country { get; set; }
public string PostalCode { get; set; }
public string Phone { get; set; }
public string CompanyName { get; set; }
[ForeignKey( "Customer" )]
public int CustomerID { get; set; }
public virtual Customer Customer { get; set; }
}
Programming 193
.NET Application Programming
{
modelBuilder.Entity<Contact>().ToTable( "Contacts",
"GROUPO" );
modelBuilder.Entity<Customer>().ToTable( "Customers",
"GROUPO" );
}
}
}
Programming 195
.NET Application Programming
The version number must match the version of the provider that you are installing. The
configuration file is located in \WINDOWS\Microsoft.NET\Framework
\v2.0.50727\CONFIG. For 64-bit Windows systems, there is a second configuration file
under the Framework64 tree that must also be modified.
There are four types of trace listeners referenced in the configuration file shown above.
Programming 197
.NET Application Programming
The nnn is an integer representing the scope nesting level 1, 2, 3, ... The optional
parameter_names is a list of parameter names separated by spaces.
• SATracePoolingSwitch – All connection pooling is logged. Trace messages have any of
the following forms.
<sa.ConnectionPool.AllocateConnection|CPOOL>
connectionString='connection_text'
<sa.ConnectionPool.RemoveConnection|CPOOL>
connectionString='connection_text'
<sa.ConnectionPool.ReturnConnection|CPOOL>
connectionString='connection_text'
<sa.ConnectionPool.ReuseConnection|CPOOL>
connectionString='connection_text'
• SATracePropertySwitch – All property setting and retrieval is logged. Trace messages
have any of the following forms.
<sa.class_name.get_property_name|API> object_id#
<sa.class_name.set_property_name|API> object_id#
Prerequisites
You must have Visual Studio installed.
Task
Programming 199
.NET Application Programming
When the application finishes execution, the trace output is recorded in the bin\Debug
\myTrace.log file.
Next
View the trace log in the Output window of Visual Studio.
Prerequisites
You must have Visual Studio and the .NET Framework installed on your computer.
You must have the SELECT ANY TABLE system privilege.
Task
The Simple project is included with the SAP Sybase IQ samples. It demonstrates a simple
listbox that is filled with the names from the Employees table.
5. You must also add a using directive to your source code to reference the Data Provider
classes. This has already been done in the Simple code sample. To view the using
directive:
• Open the source code for the project. In the Solution Explorer window, right-click
Form1.cs and click View Code.
In the using directives in the top section, you should see the following line:
using iAnywhere.Data.SQLAnywhere;
This line is required for C# projects. If you are using Visual Basic .NET, you need to
add an Imports line to your source code.
6. Click Debug » Start Without Debugging or press Ctrl+F5 to run the Simple sample.
7. In the SQL Anywhere Sample window, click Connect.
The application connects to the SAP Sybase IQ sample database and puts the surname of
each employee in the window, as follows:
8. Close the SQL Anywhere Sample window to shut down the application and disconnect
from the sample database. This also shuts down the database server.
You have built and executed a simple .NET application that uses the SAP Sybase IQ .NET
Data Provider to obtain a result set from an SAP Sybase IQ database server.
Prerequisites
You must have Visual Studio and the .NET Framework installed on your computer.
You must have the SELECT ANY TABLE system privilege.
Programming 201
.NET Application Programming
Task
The TableViewer project is included with the SAP Sybase IQ samples. The Table Viewer
project is more complex than the Simple project. You can use it to connect to a database, select
a table, and execute SQL statements on the database.
This line is required for C# projects. If you are using Visual Basic, you need to add an
Imports line to your source code.
6. Click Debug » Start Without Debugging or press Ctrl+F5 to run the Table Viewer
sample.
The application connects to the SAP Sybase IQ sample database.
7. In the Table Viewer window, click Connect.
8. In the Table Viewer window, click Execute.
The application retrieves the data from the Employees table in the sample database and
puts the query results in the Results datagrid, as follows:
You can also execute other SQL statements from this application: type a SQL statement in
the SQL Statement pane, and then click Execute.
9. Close the Table Viewer window to shut down the application and disconnect from the
sample database. This also shuts down the database server.
You have built and executed a .NET application that uses the .NET Data Provider to connect to
a database, execute SQL statements, and display the results using a DataGrid object.
Prerequisites
You must have the SELECT ANY TABLE system privilege.
Prerequisites
You must have Visual Studio and the .NET Framework installed on your computer.
Programming 203
.NET Application Programming
This lesson assumes that you have the roles and privileges listed in the Privileges section at the
start of this tutorial: Tutorial: Developing a simple .NET database application with Visual
Studio.
Task
This tutorial is based on Visual Studio and the .NET Framework. The complete application
can be found in the ADO.NET project %ALLUSERSPROFILE%\SybaseIQ\samples
\SQLAnywhere\ADO.NET\SimpleViewer\SimpleViewer.sln.
Programming 205
.NET Application Programming
A dataset control and several labeled text fields appear on the form.
10. On the form, click the picture box next to Photo.
a. Change the shape of the box to a square.
b. Click the right-arrow in the upper-right corner of the picture box.
The Picture Box Tasks window opens.
c. From the Size Mode dropdown list, click Zoom.
d. To close the Picture Box Tasks window, click anywhere outside the window.
11. Build and run the project.
a. Click Build » Build Solution.
b. Click Debug » Start Debugging.
The application connects to the SAP Sybase IQ sample database and displays the first
row of the Products table in the text boxes and picture box.
c. You can use the buttons on the control to scroll through the rows of the result set.
d. You can go directly to a row in the result set by entering the row number in the scroll
control.
e. You can update values in the result set using the text boxes and save them by clicking
the Save Data button.
12. Shut down the application and then save your project.
You have now created a simple, yet powerful, .NET application using Visual Studio, the
Server Explorer, and the SAP Sybase IQ .NET Data Provider.
Next
In the next lesson, you add a datagrid control to the form developed in this lesson.
Prerequisites
This lesson assumes that you have the roles and privileges listed in the Privileges section at the
start of this tutorial: Tutorial: Using Java in the databasTutorial: Developing a Simple .NET
Database Application with Visual Studio.
Task
The complete application can be found in the ADO.NET project %ALLUSERSPROFILE%
\SybaseIQ\samples\SQLAnywhere\ADO.NET\SimpleViewer
\SimpleViewer.sln.
Programming 207
.NET Application Programming
You can also use the other control on the form to move through the rows of the result set.
It would be ideal, however, if both controls could stay synchronized with each other. The
next few steps show how to do this.
12. Shut down the application and then save your project.
13. Delete the Fill strip on the form since you do not need it.
• On the design form (Form1), right-click the Fill strip to the right of the word Fill, then
click Delete.
The Fill strip is removed from the form.
14. Synchronize the two controls as follows.
a. On the design form (Form1), right-click the ID text box, then click Properties.
b. Click the Events button (it appears as a lightning bolt).
c. Scroll down until you find the TextChanged event.
Programming 209
.NET Application Programming
16. Shut down the application and then save your project.
You have now added a control that updates automatically as you navigate through the result
set.
In this tutorial, you saw how the powerful combination of Microsoft Visual Studio, the Server
Explorer, and the SAP Sybase IQ .NET Data Provider can be used to create database
applications.
SAInfoMessageEventHandler(object, SAInfoMessageEventArgs )
delegate
Represents the method that handles the SAConnection.InfoMessage event of an
SAConnection object.
C# syntax
public delegate void SAInfoMessageEventHandler (object obj,
SAInfoMessageEventArgs args);
SARowsCopiedEventHandler(object, SARowsCopiedEventArgs )
delegate
Represents the method that handles the SABulkCopy.SARowsCopied event of an
SABulkCopy.
C# syntax
public delegate void SARowsCopiedEventHandler (object sender,
SARowsCopiedEventArgs rowsCopiedEventArgs);
Usage
The SARowsCopiedEventHandler delegate is not available in the .NET Compact Framework
2.0.
Programming 211
.NET Application Programming
SARowUpdatedEventHandler(object, SARowUpdatedEventArgs )
delegate
Represents the method that handles the RowUpdated event of an SADataAdapter.
C# syntax
public delegate void SARowUpdatedEventHandler (object sender,
SARowUpdatedEventArgs e);
SARowUpdatingEventHandler(object, SARowUpdatingEventArgs )
delegate
Represents the method that handles the RowUpdating event of an SADataAdapter.
C# syntax
public delegate void SARowUpdatingEventHandler (object sender,
SARowUpdatingEventArgs e);
SABulkCopyOptions() enumeration
A bitwise flag that specifies one or more options to use with an instance of SABulkCopy.
SAIsolationLevel() enumeration
Specifies SQL Anywhere isolation levels.
SABulkCopy class
Efficiently bulk load a SQL Anywhere table with data from another source.
C# syntax
public sealed class SABulkCopy : System.IDisposable
Remarks
The SABulkCopy class is not available in the .NET Compact Framework 2.0.
Implements: System.IDisposable
Custom Attribute: sealed
Close() method
Closes the SABulkCopy instance.
C# syntax
public void Close ()
Programming 213
.NET Application Programming
BatchSize property
Gets or sets the number of rows in each batch.
C# syntax
public int BatchSize {get;set;}
Remarks
At the end of each batch, the rows in the batch are sent to the server.
The number of rows in each batch. The default is 0.
Setting this property to zero causes all the rows to be sent in one batch.
Setting this property to a value less than zero is an error.
If this value is changed while a batch is in progress, the current batch completes and any
further batches use the new value.
BulkCopyTimeout property
Gets or sets the number of seconds for the operation to complete before it times out.
C# syntax
public int BulkCopyTimeout {get;set;}
Remarks
The default value is 30 seconds.
A value of zero indicates no limit. This should be avoided because it may cause an indefinite
wait.
If the operation times out, then all rows in the current transaction are rolled back and an
SAException is raised.
Setting this property to a value less than zero is an error.
ColumnMappings property
Returns a collection of SABulkCopyColumnMapping items.
C# syntax
public SABulkCopyColumnMappingCollection ColumnMappings {get;}
Remarks
Column mappings define the relationships between columns in the data source and columns in
the destination.
By default, it is an empty collection.
The property cannot be modified while WriteToServer is executing.
If ColumnMappings is empty when WriteToServer is executed, then the first column in the
source is mapped to the first column in the destination, the second to the second, and so on.
This takes place as long as the column types are convertible, there are at least as many
destination columns as source columns, and any extra destination columns are nullable.
DestinationTableName property
Gets or sets the name of the destination table on the server.
C# syntax
public string DestinationTableName {get;set;}
Remarks
The default value is a null reference. In Visual Basic it is Nothing.
If the value is changed while WriteToServer is executing, the change has no effect.
If the value has not been set before a call to WriteToServer, an InvalidOperationException is
raised.
It is an error to set the value to NULL or the empty string.
Programming 215
.NET Application Programming
NotifyAfter property
Gets or sets the number of rows to be processed before generating a notification event.
C# syntax
public int NotifyAfter {get;set;}
Remarks
Zero is returned if the property has not been set.
Changes made to NotifyAfter, while executing WriteToServer, do not take effect until after the
next notification.
Setting this property to a value less than zero is an error.
The values of NotifyAfter and BulkCopyTimeout are mutually exclusive, so the event can fire
even if no rows have been sent to the database or committed.
SARowsCopied() event
This event occurs every time the number of rows specified by the NotifyAfter property have
been processed.
C# syntax
public event SARowsCopiedEventHandler SARowsCopied;
Usage
The receipt of an SARowsCopied event does not imply that any rows have been sent to the
database server or committed. You cannot call the Close method from this event.
SABulkCopyColumnMapping class
Defines the mapping between a column in an SABulkCopy instance's data source and a
column in the instance's destination table.
C# syntax
public sealed class SABulkCopyColumnMapping
Remarks
The SABulkCopyColumnMapping class is not available in the .NET Compact Framework
2.0.
Custom Attribute: sealed
DestinationColumn property
Gets or sets the name of the column in the destination database table being mapped to.
C# syntax
public string DestinationColumn {get;set;}
Remarks
A string specifying the name of the column in the destination table or a null reference (Nothing
in Visual Basic) if the DestinationOrdinal property has priority.
The DestinationColumn property and DestinationOrdinal property are mutually exclusive.
The most recently set value takes priority.
Setting the DestinationColumn property causes the DestinationOrdinal property to be set to
-1. Setting the DestinationOrdinal property causes the DestinationColumn property to be set
to a null reference (Nothing in Visual Basic).
It is an error to set DestinationColumn to null or the empty string.
DestinationOrdinal property
Gets or sets the ordinal value of the column in the destination table being mapped to.
C# syntax
public int DestinationOrdinal {get;set;}
Remarks
An integer specifying the ordinal of the column being mapped to in the destination table or -1
if the property is not set.
The DestinationColumn property and DestinationOrdinal property are mutually exclusive.
The most recently set value takes priority.
Programming 217
.NET Application Programming
SourceColumn property
Gets or sets the name of the column being mapped in the data source.
C# syntax
public string SourceColumn {get;set;}
Remarks
A string specifying the name of the column in the data source or a null reference (Nothing in
Visual Basic) if the SourceOrdinal property has priority.
The SourceColumn property and SourceOrdinal property are mutually exclusive. The most
recently set value takes priority.
Setting the SourceColumn property causes the SourceOrdinal property to be set to -1. Setting
the SourceOrdinal property causes the SourceColumn property to be set to a null reference
(Nothing in Visual Basic).
It is an error to set SourceColumn to null or the empty string.
SourceOrdinal property
Gets or sets ordinal position of the source column within the data source.
C# syntax
public int SourceOrdinal {get;set;}
Remarks
An integer specifying the ordinal of the column in the data source or -1 if the property is not
set.
The SourceColumn property and SourceOrdinal property are mutually exclusive. The most
recently set value takes priority.
Setting the SourceColumn property causes the SourceOrdinal property to be set to -1. Setting
the SourceOrdinal property causes the SourceColumn property to be set to a null reference
(Nothing in Visual Basic).
SABulkCopyColumnMappingCollection class
A collection of SABulkCopyColumnMapping objects that inherits from
System.Collections.CollectionBase.
C# syntax
public sealed class SABulkCopyColumnMappingCollection :
System.Collections.CollectionBase
Remarks
The SABulkCopyColumnMappingCollection class is not available in the .NET Compact
Framework 2.0.
Implements: ICollection, IEnumerable, IList
Custom Attribute: sealed
DestinationOrdinalComparer class
C# syntax
private class DestinationOrdinalComparer :
System.Collections.IComparer
DestinationOrdinalComparer() constructor
C# syntax
public DestinationOrdinalComparer ()
Programming 219
.NET Application Programming
C# syntax
public int Compare (object o1, object o2)
C# syntax
public bool Contains ( SABulkCopyColumnMapping value)
Parameters
• value – A valid SABulkCopyColumnMapping object.
Returns
True if the specified mapping exists in the collection; otherwise, false.
C# syntax
public void CopyTo ( SABulkCopyColumnMapping[] array, int
index)
Parameters
• array – The one-dimensional SABulkCopyColumnMapping array that is the destination
of the elements copied from SABulkCopyColumnMappingCollection. The array must
have zero-based indexing.
• index – The zero-based index in the array at which copying begins.
C# syntax
public int IndexOf ( SABulkCopyColumnMapping value)
Parameters
• value – The SABulkCopyColumnMapping object to search for.
Returns
The zero-based index of the column mapping is returned, or -1 is returned if the column
mapping is not found in the collection.
C# syntax
public void Remove ( SABulkCopyColumnMapping value)
Parameters
• value – The SABulkCopyColumnMapping object to be removed from the collection.
RemoveAt(int) method
Removes the mapping at the specified index from the collection.
C# syntax
public new void RemoveAt (int index)
Programming 221
.NET Application Programming
Parameters
• index – The zero-based index of the SABulkCopyColumnMapping object to be removed
from the collection.
this property
Gets the SABulkCopyColumnMapping object at the specified index.
C# syntax
public SABulkCopyColumnMapping this {get;}
DestinationOrdinalComparer class
C# syntax
private class DestinationOrdinalComparer :
System.Collections.IComparer
DestinationOrdinalComparer() constructor
C# syntax
public DestinationOrdinalComparer ()
C# syntax
public int Compare (object o1, object o2)
SACommLinksOptionsBuilder class
Provides a simple way to create and manage the CommLinks options portion of connection
strings used by the SAConnection class.
C# syntax
public sealed class SACommLinksOptionsBuilder
Remarks
The SACommLinksOptionsBuilder class is not available in the .NET Compact Framework
2.0.
For a list of connection parameters, see Connection parameters.
Custom Attribute: sealed
GetUseLongNameAsKeyword() method
Gets a boolean values that indicates whether long connection parameter names are used in the
connection string.
C# syntax
public bool GetUseLongNameAsKeyword ()
Returns
True if long connection parameter names are used to build connection strings; otherwise,
false.
Usage
SQL Anywhere connection parameters have both long and short forms of their names. For
example, to specify the name of an ODBC data source in your connection string, you can use
either of the following values: DataSourceName or DSN. By default, long connection
parameter names are used to build connection strings.
Programming 223
.NET Application Programming
SetUseLongNameAsKeyword(bool) method
Sets a boolean value that indicates whether long connection parameter names are used in the
connection string.
C# syntax
public void SetUseLongNameAsKeyword (bool useLongNameAsKeyword)
Parameters
• useLongNameAsKeyword – A boolean value that indicates whether the long connection
parameter name is used in the connection string.
Usage
Long connection parameter names are used by default.
ToString() method
Converts the SACommLinksOptionsBuilder object to a string representation.
C# syntax
public override string ToString ()
Returns
The options string being built.
All property
Gets or sets the ALL CommLinks option.
C# syntax
public bool All {get;set;}
Remarks
Attempt to connect using the shared memory protocol first, followed by all remaining and
available communication protocols. Use this setting if you are unsure of which
communication protocol(s) to use.
ConnectionString property
Gets or sets the connection string being built.
C# syntax
public string ConnectionString {get;set;}
Remarks
The SACommLinksOptionsBuilder class is not available in the .NET Compact Framework
2.0.
SharedMemory property
Gets or sets the SharedMemory protocol.
C# syntax
public bool SharedMemory {get;set;}
Remarks
The SACommLinksOptionsBuilder class is not available in the .NET Compact Framework
2.0.
TcpOptionsBuilder property
Gets or sets an SATcpOptionsBuilder object used to create a TCP options string.
C# syntax
public SATcpOptionsBuilder TcpOptionsBuilder {get;set;}
TcpOptionsString property
Gets or sets a string of TCP options.
Programming 225
.NET Application Programming
C# syntax
public string TcpOptionsString {get;set;}
SACommand class
A SQL statement or stored procedure that is executed against a SQL Anywhere database.
C# syntax
public sealed class SACommand : System.Data.Common.DbCommand,
System.ICloneable
Remarks
Implements: IDbCommand, ICloneable
For more information, see Accessing and manipulating data.
Custom Attribute: sealed
Cancel() method
Cancels the execution of an SACommand object.
C# syntax
public override void Cancel ()
Usage
If there is nothing to cancel, nothing happens. If there is a command in process, a "Statement
interrupted by user" exception is thrown.
CreateDbParameter() method
Creates a new instance of a System.Data.Common.DbParameter object.
C# syntax
protected override DbParameter CreateDbParameter ()
Returns
A System.Data.Common.DbParameter object.
CreateParameter() method
Provides an SAParameter object for supplying parameters to SACommand objects.
C# syntax
public new SAParameter CreateParameter ()
Returns
A new parameter, as an SAParameter object.
Usage
Stored procedures and some other SQL statements can take parameters, indicated in the text of
a statement by a question mark (?).
The CreateParameter method provides an SAParameter object. You can set properties on the
SAParameter to specify the value, data type, and so on for the parameter.
Dispose(bool) method
Frees the resources associated with the object.
C# syntax
protected override void Dispose (bool disposing)
C# syntax
public int EndExecuteNonQuery ( IAsyncResult asyncResult)
Programming 227
.NET Application Programming
Parameters
• asyncResult – The IAsyncResult returned by the call to
SACommand.BeginExecuteNonQuery.
Returns
The number of rows affected (the same behavior as SACommand.ExecuteNonQuery).
Exceptions
• ArgumentException – The asyncResult parameter is null (Nothing in Microsoft Visual
Basic).
• InvalidOperationException – The SACommand.EndExecuteNonQuery(IAsyncResult)
was called more than once for a single command execution, or the method was
mismatched against its execution method.
Usage
You must call EndExecuteNonQuery once for every call to BeginExecuteNonQuery. The call
must be after BeginExecuteNonQuery has returned. ADO.NET is not thread safe; it is your
responsibility to ensure that BeginExecuteNonQuery has returned. The IAsyncResult passed
to EndExecuteNonQuery must be the same as the one returned from the
BeginExecuteNonQuery call that is being completed. It is an error to call
EndExecuteNonQuery to end a call to BeginExecuteReader, and vice versa.
If an error occurs while executing the command, the exception is thrown when
EndExecuteNonQuery is called.
There are four ways to wait for execution to complete:
(1) Call EndExecuteNonQuery.
Calling EndExecuteNonQuery blocks until the command completes. For example:
Programming 229
.NET Application Programming
conn );
IAsyncResult res = cmd.BeginExecuteNonQuery( callbackFunction,
cmd );
// perform other work. The callback function will be
// called when the command completes
}
The callback function executes in a separate thread, so the usual caveats related to updating the
user interface in a threaded program apply.
C# syntax
public SADataReader EndExecuteReader ( IAsyncResult
asyncResult)
Parameters
• asyncResult – The IAsyncResult returned by the call to
SACommand.BeginExecuteReader.
Returns
An SADataReader object that can be used to retrieve the requested rows (the same behavior as
SACommand.ExecuteReader).
Exceptions
• ArgumentException – The asyncResult parameter is null (Nothing in Microsoft Visual
Basic)
• InvalidOperationException – The SACommand.EndExecuteReader(IAsyncResult)
was called more than once for a single command execution, or the method was
mismatched against its execution method.
Usage
You must call EndExecuteReader once for every call to BeginExecuteReader. The call must be
after BeginExecuteReader has returned. ADO.NET is not thread safe; it is your responsibility
to ensure that BeginExecuteReader has returned. The IAsyncResult passed to
EndExecuteReader must be the same as the one returned from the BeginExecuteReader call
that is being completed. It is an error to call EndExecuteReader to end a call to
BeginExecuteNonQuery, and vice versa.
If an error occurs while executing the command, the exception is thrown when
EndExecuteReader is called.
There are four ways to wait for execution to complete:
(1) Call EndExecuteReader.
Calling EndExecuteReader blocks until the command completes. For example:
Programming 231
.NET Application Programming
The callback function executes in a separate thread, so the usual caveats related to updating the
user interface in a threaded program apply.
ExecuteDbDataReader(CommandBehavior) method
Executes the command text against the connection.
C# syntax
protected override DbDataReader ExecuteDbDataReader
(CommandBehavior behavior)
Parameters
• behavior – An instance of System.Data.CommandBehavior.
Returns
A System.Data.Common.DbDataReader.
ExecuteNonQuery() method
Executes a statement that does not return a result set, such as an INSERT, UPDATE, DELETE,
or data definition statement.
C# syntax
public override int ExecuteNonQuery ()
Returns
The number of rows affected.
Usage
You can use ExecuteNonQuery to change the data in a database without using a DataSet. Do
this by executing UPDATE, INSERT, or DELETE statements.
Although ExecuteNonQuery does not return any rows, output parameters or return values that
are mapped to parameters are populated with data.
For UPDATE, INSERT, and DELETE statements, the return value is the number of rows
affected by the command. For all other types of statements, and for rollbacks, the return value
is -1.
ExecuteScalar() method
Executes a statement that returns a single value.
C# syntax
public override object ExecuteScalar ()
Returns
The first column of the first row in the result set, or a null reference if the result set is empty.
Usage
If this method is called on a query that returns multiple rows and columns, only the first
column of the first row is returned.
Prepare() method
Prepares or compiles the SACommand on the data source.
C# syntax
public override void Prepare ()
Usage
If you call one of the ExecuteNonQuery, ExecuteReader, or ExecuteScalar methods after
calling Prepare, any parameter value that is larger than the value specified by the Size property
Programming 233
.NET Application Programming
is automatically truncated to the original specified size of the parameter, and no truncation
errors are returned.
The truncation only happens for the following data types:
• CHAR
• VARCHAR
• LONG VARCHAR
• TEXT
• NCHAR
• NVARCHAR
• LONG NVARCHAR
• NTEXT
• BINARY
• LONG BINARY
• VARBINARY
• IMAGE
If the size property is not specified, and so is using the default value, the data is not truncated.
ResetCommandTimeout() method
Resets the CommandTimeout property to its default value of 30 seconds.
C# syntax
public void ResetCommandTimeout ()
CommandText property
Gets or sets the text of a SQL statement or stored procedure.
C# syntax
public override string CommandText {get;set;}
Remarks
The SQL statement or the name of the stored procedure to execute. The default is an empty
string.
CommandTimeout property
This feature is not supported by the SQL Anywhere .NET Data Provider.
C# syntax
public override int CommandTimeout {get;set;}
Remarks
To set a request timeout, use the following example.
cmd.CommandText = "SET OPTION request_timeout = 30";
cmd.ExecuteNonQuery();
CommandType property
Gets or sets the type of command represented by an SACommand.
C# syntax
public override CommandType CommandType {get;set;}
Remarks
One of the System.Data.CommandType values. The default is
System.Data.CommandType.Text.
Supported command types are as follows:
• System.Data.CommandType.StoredProcedure When you specify this CommandType, the
command text must be the name of a stored procedure and you must supply any arguments
as SAParameter objects.
• System.Data.CommandType.Text This is the default value.
When the CommandType property is set to StoredProcedure, the CommandText property
should be set to the name of the stored procedure. The command executes this stored
procedure when you call one of the Execute methods.
Use a question mark (?) placeholder to pass parameters. For example:
SELECT * FROM Customers WHERE ID = ?
The order in which SAParameter objects are added to the SAParameterCollection must
directly correspond to the position of the question mark placeholder for the parameter.
Programming 235
.NET Application Programming
Connection property
Gets or sets the connection object to which the SACommand object applies.
C# syntax
public new SAConnection Connection {get;set;}
Remarks
The default value is a null reference. In Visual Basic it is Nothing.
DbConnection property
Gets or sets the System.Data.Common.DbConnection used by this SACommand object.
C# syntax
protected override DbConnection DbConnection {get;set;}
Remarks
The connection to the data source.
DbParameterCollection property
Gets the collection of System.Data.Common.DbParameter objects.
C# syntax
protected override DbParameterCollection
DbParameterCollection {get;}
Remarks
The parameters of the SQL statement or stored procedure.
DbTransaction property
Gets or sets the System.Data.Common.DbTransaction within which this SACommand object
executes.
C# syntax
protected override DbTransaction DbTransaction {get;set;}
Remarks
The transaction within which a Command object of a .NET Framework data provider
executes. The default value is a null reference (Nothing in Visual Basic).
DesignTimeVisible property
Gets or sets a value that indicates if the SACommand should be visible in a Windows Form
Designer control.
C# syntax
public override bool DesignTimeVisible {get;set;}
Remarks
The default is true.
True if this SACommand instance should be visible, false if this instance should not be visible.
The default is false.
Parameters property
A collection of parameters for the current statement.
C# syntax
public new SAParameterCollection Parameters {get;}
Remarks
Use question marks in the CommandText to indicate parameters.
Programming 237
.NET Application Programming
The parameters of the SQL statement or stored procedure. The default value is an empty
collection.
When CommandType is set to Text, pass parameters using the question mark placeholder. For
example:
SELECT * FROM Customers WHERE ID = ?
The order in which SAParameter objects are added to the SAParameterCollection must
directly correspond to the position of the question mark placeholder for the parameter in the
command text.
When the parameters in the collection do not match the requirements of the query to be
executed, an error may result or an exception may be thrown.
Transaction property
Specifies the SATransaction object in which the SACommand executes.
C# syntax
public new SATransaction Transaction {get;set;}
Remarks
The default value is a null reference. In Visual Basic, this is Nothing.
You cannot set the Transaction property if it is already set to a specific value and the command
is executing. If you set the transaction property to an SATransaction object that is not
connected to the same SAConnection object as the SACommand object, an exception will be
thrown the next time you attempt to execute a statement.
For more information, see Transaction processing.
UpdatedRowSource property
Gets or sets how command results are applied to the DataRow when used by the Update
method of the SADataAdapter.
C# syntax
public override UpdateRowSource UpdatedRowSource {get;set;}
Remarks
One of the UpdatedRowSource values. The default value is
UpdateRowSource.OutputParameters. If the command is automatically generated, this
property is UpdateRowSource.None.
UpdatedRowSource.Both, which returns both resultset and output parameters, is not
supported.
SACommandBuilder class
A way to generate single-table SQL statements that reconcile changes made to a DataSet with
the data in the associated database.
C# syntax
public sealed class SACommandBuilder :
System.Data.Common.DbCommandBuilder
Remarks
Custom Attribute: sealed
C# syntax
protected override void ApplyParameterInfo ( DbParameter
parameter, DataRow row, StatementType statementType, bool
whereClause)
Parameters
• parameter – A System.Data.Common.DbParameter to which the additional
modifications are applied.
• row – The System.Data.DataRow from the schema table provided by
SADataReader.GetSchemaTable.
Programming 239
.NET Application Programming
C# syntax
public static void DeriveParameters ( SACommand command)
Parameters
• command – An SACommand object for which to derive parameters.
Usage
This is used for the stored procedure specified in the SACommand.
DeriveParameters overwrites any existing parameter information for the SACommand.
DeriveParameters requires an extra call to the database server. If the parameter information is
known in advance, it is more efficient to populate the Parameters collection by setting the
information explicitly.
GetParameterPlaceholder(int) method
Returns the placeholder for the parameter in the associated SQL statement.
C# syntax
protected override string GetParameterPlaceholder (int index)
Parameters
• index – The number to be included as part of the parameter's name.
Returns
The name of the parameter with the specified number appended.
C# syntax
protected override DataTable GetSchemaTable ( DbCommand
sourceCommand)
Parameters
• sourceCommand – The System.Data.Common.DbCommand for which to retrieve the
corresponding schema table.
Returns
A System.Data.DataTable that represents the schema for the specific
System.Data.Common.DbCommand.
C# syntax
protected override DbCommand InitializeCommand ( DbCommand
command)
Parameters
• command – The System.Data.Common.DbCommand to be used by the command
builder for the corresponding insert, update, or delete command.
Returns
A System.Data.Common.DbCommand instance to use for each insert, update, or delete
operation. Passing a null value allows the InitializeCommand method to create a
Programming 241
.NET Application Programming
QuoteIdentifier(string) method
Returns the correct quoted form of an unquoted identifier, including properly escaping any
embedded quotes in the identifier.
C# syntax
public override string QuoteIdentifier (string unquotedIdentifier)
Parameters
• unquotedIdentifier – The string representing the unquoted identifier that will have be
quoted.
Returns
Returns a string representing the quoted form of an unquoted identifier with embedded quotes
properly escaped.
C# syntax
protected override void SetRowUpdatingHandler ( DbDataAdapter
adapter)
Parameters
• adapter – The SADataAdapter object to be used for the update.
UnquoteIdentifier(string) method
Returns the correct unquoted form of a quoted identifier, including properly un-escaping any
embedded quotes in the identifier.
C# syntax
public override string UnquoteIdentifier (string quotedIdentifier)
Parameters
• quotedIdentifier – The string representing the quoted identifier that will have its
embedded quotes removed.
Returns
Returns a string representing the unquoted form of a quoted identifier with embedded quotes
properly un-escaped.
DataAdapter property
Specifies the SADataAdapter for which to generate statements.
C# syntax
public new SADataAdapter DataAdapter {get;set;}
Remarks
An SADataAdapter object.
When you create a new instance of SACommandBuilder, any existing SACommandBuilder
that is associated with this SADataAdapter is released.
SAConnectionStringBuilder class
Provides a simple way to create and manage the contents of connection strings used by the
SAConnection class.
Programming 243
.NET Application Programming
C# syntax
public sealed class SAConnectionStringBuilder :
SAConnectionStringBuilderBase
Remarks
The SAConnectionStringBuilder class inherits SAConnectionStringBuilderBase, which
inherits DbConnectionStringBuilder.
The SAConnectionStringBuilder class is not available in the .NET Compact Framework 2.0.
For a list of connection parameters, see Connection parameters.
Custom Attribute: sealed
ContainsKey(string) method
Determines whether the SAConnectionStringBuilder object contains a specific keyword.
C# syntax
public override bool ContainsKey (string keyword)
Parameters
• keyword – The keyword to locate in the SAConnectionStringBuilder.
Returns
True if the value associated with keyword has been set; otherwise, false.
Examples
The following statement determines whether the SAConnectionStringBuilder object contains
the UserID keyword.
connectString.ContainsKey("UserID")
GetUseLongNameAsKeyword() method
Gets a boolean values that indicates whether long connection parameter names are used in the
connection string.
C# syntax
public bool GetUseLongNameAsKeyword ()
Returns
True if long connection parameter names are used to build connection strings; otherwise,
false.
Usage
SQL Anywhere connection parameters have both long and short forms of their names. For
example, to specify the name of an ODBC data source in your connection string, you can use
either of the following values: DataSourceName or DSN. By default, long connection
parameter names are used to build connection strings.
Remove(string) method
Removes the entry with the specified key from the SAConnectionStringBuilder instance.
C# syntax
public override bool Remove (string keyword)
Parameters
• keyword – The key of the key/value pair to be removed from the connection string in this
SAConnectionStringBuilder.
Returns
True if the key existed within the connection string and was removed; false if the key did not
exist.
SetUseLongNameAsKeyword(bool) method
Sets a boolean value that indicates whether long connection parameter names are used in the
connection string.
C# syntax
public void SetUseLongNameAsKeyword (bool useLongNameAsKeyword)
Programming 245
.NET Application Programming
Parameters
• useLongNameAsKeyword – A boolean value that indicates whether the long connection
parameter name is used in the connection string.
Usage
Long connection parameter names are used by default.
ShouldSerialize(string) method
Indicates whether the specified key exists in this SAConnectionStringBuilder instance.
C# syntax
public override bool ShouldSerialize (string keyword)
Parameters
• keyword – The key to locate in the SAConnectionStringBuilder.
Returns
True if the SAConnectionStringBuilder contains an entry with the specified key; otherwise
false.
C# syntax
public override bool TryGetValue (string keyword, out object
value)
Parameters
• keyword – The key of the item to retrieve.
• value – The value corresponding to keyword.
Returns
true if keyword was found within the connection string; otherwise false.
AppInfo property
Gets or sets the AppInfo connection property.
C# syntax
public string AppInfo {get;set;}
AutoStart property
Gets or sets the AutoStart connection property.
C# syntax
public string AutoStart {get;set;}
AutoStop property
Gets or sets the AutoStop connection property.
C# syntax
public string AutoStop {get;set;}
Charset property
Gets or sets the Charset connection property.
C# syntax
public string Charset {get;set;}
CommBufferSize property
Gets or sets the CommBufferSize connection property.
Programming 247
.NET Application Programming
C# syntax
public int CommBufferSize {get;set;}
CommLinks property
Gets or sets the CommLinks property.
C# syntax
public string CommLinks {get;set;}
Compress property
Gets or sets the Compress connection property.
C# syntax
public string Compress {get;set;}
CompressionThreshold property
Gets or sets the CompressionThreshold connection property.
C# syntax
public int CompressionThreshold {get;set;}
ConnectionLifetime property
Gets or sets the ConnectionLifetime connection property.
C# syntax
public int ConnectionLifetime {get;set;}
ConnectionName property
Gets or sets the ConnectionName connection property.
C# syntax
public string ConnectionName {get;set;}
ConnectionPool property
Gets or sets the ConnectionPool property.
C# syntax
public string ConnectionPool {get;set;}
ConnectionReset property
Gets or sets the ConnectionReset connection property.
C# syntax
public bool ConnectionReset {get;set;}
Remarks
A DataTable that contains schema information.
ConnectionTimeout property
Gets or sets the ConnectionTimeout connection property.
C# syntax
public int ConnectionTimeout {get;set;}
The following statement displays the value of the ConnectionTimeout property.
MessageBox.Show( connString.ConnectionTimeout.ToString() );
Programming 249
.NET Application Programming
DatabaseFile property
Gets or sets the DatabaseFile connection property.
C# syntax
public string DatabaseFile {get;set;}
DatabaseKey property
Gets or sets the DatabaseKey connection property.
C# syntax
public string DatabaseKey {get;set;}
DatabaseName property
Gets or sets the DatabaseName connection property.
C# syntax
public string DatabaseName {get;set;}
DatabaseSwitches property
Gets or sets the DatabaseSwitches connection property.
C# syntax
public string DatabaseSwitches {get;set;}
DataSourceName property
Gets or sets the DataSourceName connection property.
C# syntax
public string DataSourceName {get;set;}
DisableMultiRowFetch property
Gets or sets the DisableMultiRowFetch connection property.
C# syntax
public string DisableMultiRowFetch {get;set;}
Elevate property
Gets or sets the Elevate connection property.
C# syntax
public string Elevate {get;set;}
EncryptedPassword property
Gets or sets the EncryptedPassword connection property.
C# syntax
public string EncryptedPassword {get;set;}
Encryption property
Gets or sets the Encryption connection property.
C# syntax
public string Encryption {get;set;}
Programming 251
.NET Application Programming
Enlist property
Gets or sets the Enlist connection property.
C# syntax
public bool Enlist {get;set;}
FileDataSourceName property
Gets or sets the FileDataSourceName connection property.
C# syntax
public string FileDataSourceName {get;set;}
ForceStart property
Gets or sets the ForceStart connection property.
C# syntax
public string ForceStart {get;set;}
Host property
Gets or sets the Host property.
C# syntax
public string Host {get;set;}
IdleTimeout property
Gets or sets the IdleTimeout connection property.
C# syntax
public int IdleTimeout {get;set;}
InitString property
Gets or sets the InitString connection property.
C# syntax
public string InitString {get;set;}
Integrated property
Gets or sets the Integrated connection property.
C# syntax
public string Integrated {get;set;}
Kerberos property
Gets or sets the Kerberos connection property.
C# syntax
public string Kerberos {get;set;}
Keys property
Gets an System.Collections.ICollection that contains the keys in the
SAConnectionStringBuilder.
C# syntax
public override ICollection Keys {get;}
Remarks
An System.Collections.ICollection that contains the keys in the SAConnectionStringBuilder.
Programming 253
.NET Application Programming
Language property
Gets or sets the Language connection property.
C# syntax
public string Language {get;set;}
LazyClose property
Gets or sets the LazyClose connection property.
C# syntax
public string LazyClose {get;set;}
LivenessTimeout property
Gets or sets the LivenessTimeout connection property.
C# syntax
public int LivenessTimeout {get;set;}
LogFile property
Gets or sets the LogFile connection property.
C# syntax
public string LogFile {get;set;}
MaxPoolSize property
Gets or sets the MaxPoolSize connection property.
C# syntax
public int MaxPoolSize {get;set;}
MinPoolSize property
Gets or sets the MinPoolSize connection property.
C# syntax
public int MinPoolSize {get;set;}
NewPassword property
Gets or sets the NewPassword connection property.
C# syntax
public string NewPassword {get;set;}
NodeType property
Gets or sets the NodeType property.
C# syntax
public string NodeType {get;set;}
Password property
Gets or sets the Password connection property.
C# syntax
public string Password {get;set;}
Programming 255
.NET Application Programming
PersistSecurityInfo property
Gets or sets the PersistSecurityInfo connection property.
C# syntax
public bool PersistSecurityInfo {get;set;}
Pooling property
Gets or sets the Pooling connection property.
C# syntax
public bool Pooling {get;set;}
PrefetchBuffer property
Gets or sets the PrefetchBuffer connection property.
C# syntax
public int PrefetchBuffer {get;set;}
PrefetchRows property
Gets or sets the PrefetchRows connection property.
C# syntax
public int PrefetchRows {get;set;}
Remarks
The default value is 200.
RetryConnectionTimeout property
Gets or sets the RetryConnectionTimeout property.
C# syntax
public int RetryConnectionTimeout {get;set;}
ServerName property
Gets or sets the ServerName connection property.
C# syntax
public string ServerName {get;set;}
StartLine property
Gets or sets the StartLine connection property.
C# syntax
public string StartLine {get;set;}
this property
Gets or sets the value of the connection keyword.
C# syntax
public override object this {get;set;}
Remarks
An object representing the value of the specified connection keyword.
If the keyword or type is invalid, an exception is raised. keyword is case insensitive.
When setting the value, passing NULL clears the value.
Programming 257
.NET Application Programming
Unconditional property
Gets or sets the Unconditional connection property.
C# syntax
public string Unconditional {get;set;}
UserID property
Gets or sets the UserID connection property.
C# syntax
public string UserID {get;set;}
SAConnectionStringBuilderBase class
Base class of the SAConnectionStringBuilder class.
C# syntax
public abstract class SAConnectionStringBuilderBase :
System.Data.Common.DbConnectionStringBuilder
Derived classes
• SAConnectionStringBuilder on page 243
• SATcpOptionsBuilder on page 308
Remarks
Custom Attribute: abstract
ContainsKey(string) method
Determines whether the SAConnectionStringBuilder object contains a specific keyword.
C# syntax
public override bool ContainsKey (string keyword)
Parameters
• keyword – The keyword to locate in the SAConnectionStringBuilder.
Returns
True if the value associated with keyword has been set; otherwise, false.
Examples
The following statement determines whether the SAConnectionStringBuilder object contains
the UserID keyword.
connectString.ContainsKey("UserID")
GetUseLongNameAsKeyword() method
Gets a boolean values that indicates whether long connection parameter names are used in the
connection string.
C# syntax
public bool GetUseLongNameAsKeyword ()
Returns
True if long connection parameter names are used to build connection strings; otherwise,
false.
Usage
SQL Anywhere connection parameters have both long and short forms of their names. For
example, to specify the name of an ODBC data source in your connection string, you can use
either of the following values: DataSourceName or DSN. By default, long connection
parameter names are used to build connection strings.
Remove(string) method
Removes the entry with the specified key from the SAConnectionStringBuilder instance.
Programming 259
.NET Application Programming
C# syntax
public override bool Remove (string keyword)
Parameters
• keyword – The key of the key/value pair to be removed from the connection string in this
SAConnectionStringBuilder.
Returns
True if the key existed within the connection string and was removed; false if the key did not
exist.
SetUseLongNameAsKeyword(bool) method
Sets a boolean value that indicates whether long connection parameter names are used in the
connection string.
C# syntax
public void SetUseLongNameAsKeyword (bool useLongNameAsKeyword)
Parameters
• useLongNameAsKeyword – A boolean value that indicates whether the long connection
parameter name is used in the connection string.
Usage
Long connection parameter names are used by default.
ShouldSerialize(string) method
Indicates whether the specified key exists in this SAConnectionStringBuilder instance.
C# syntax
public override bool ShouldSerialize (string keyword)
Parameters
• keyword – The key to locate in the SAConnectionStringBuilder.
Returns
True if the SAConnectionStringBuilder contains an entry with the specified key; otherwise
false.
C# syntax
public override bool TryGetValue (string keyword, out object
value)
Parameters
• keyword – The key of the item to retrieve.
• value – The value corresponding to keyword.
Returns
true if keyword was found within the connection string; otherwise false.
Keys property
Gets an System.Collections.ICollection that contains the keys in the
SAConnectionStringBuilder.
C# syntax
public override ICollection Keys {get;}
Remarks
An System.Collections.ICollection that contains the keys in the SAConnectionStringBuilder.
this property
Gets or sets the value of the connection keyword.
C# syntax
public override object this {get;set;}
Programming 261
.NET Application Programming
Remarks
An object representing the value of the specified connection keyword.
If the keyword or type is invalid, an exception is raised. keyword is case insensitive.
When setting the value, passing NULL clears the value.
SADataAdapter class
Represents a set of commands and a database connection used to fill a System.Data.DataSet
and to update a database.
C# syntax
public sealed class SADataAdapter :
System.Data.Common.DbDataAdapter, System.ICloneable
Remarks
The System.Data.DataSet provides a way to work with data offline. The SADataAdapter
provides methods to associate a DataSet with a set of SQL statements.
Implements: IDbDataAdapter, IDataAdapter, ICloneable
For more information, see Using the SADataAdapter object to access and manipulate data and
Accessing and manipulating data.
Custom Attribute: sealed
ClearBatch() method
Removes all SACommand objects from the batch.
C# syntax
protected override void ClearBatch ()
C# syntax
protected override RowUpdatedEventArgs CreateRowUpdatedEvent
(DataRow dataRow, IDbCommand command, StatementType
statementType, DataTableMapping tableMapping)
Parameters
• dataRow – The System.Data.DataRow used to update the data source.
• command – The System.Data.IDbCommand executed during the
System.Data.IDataAdapter.Update(System.Data.DataSet).
• statementType – Whether the command is an UPDATE, INSERT, DELETE, or SELECT
statement.
• tableMapping – A System.Data.Common.DataTableMapping object.
Returns
A new instance of the System.Data.Common.RowUpdatedEventArgs class.
C# syntax
protected override RowUpdatingEventArgs
CreateRowUpdatingEvent (DataRow dataRow, IDbCommand command,
StatementType statementType, DataTableMapping tableMapping)
Programming 263
.NET Application Programming
Parameters
• dataRow – The System.Data.DataRow used to update the data source.
• command – The System.Data.IDbCommand executed during the
System.Data.IDataAdapter.Update(System.Data.DataSet).
• statementType – Whether the command is an UPDATE, INSERT, DELETE, or SELECT
statement.
• tableMapping – A System.Data.Common.DataTableMapping object.
Returns
A new instance of the System.Data.Common.RowUpdatingEventArgs class.
Dispose(bool) method
Releases the unmanaged resources used by the SADataAdapter object and optionally releases
the managed resources.
C# syntax
protected override void Dispose (bool disposing)
Parameters
• disposing – True releases both managed and unmanaged resources; false releases only
unmanaged resources.
GetFillParameters() method
Returns the parameters set by you when executing a SELECT statement.
C# syntax
public new SAParameter[] GetFillParameters ()
Returns
An array of IDataParameter objects that contains the parameters set by the user.
InitializeBatching() method
Initializes batching for the SADataAdapter object.
C# syntax
protected override void InitializeBatching ()
C# syntax
protected override void OnRowUpdated ( RowUpdatedEventArgs
value)
Parameters
• value – A System.Data.Common.RowUpdatedEventArgs that contains the event data.
C# syntax
protected override void OnRowUpdating ( RowUpdatingEventArgs
value)
Parameters
• value – A System.Data.Common.RowUpdatingEventArgs that contains the event data.
TerminateBatching() method
Ends batching for the SADataAdapter object.
Programming 265
.NET Application Programming
C# syntax
protected override void TerminateBatching ()
C# syntax
protected override int Update (DataRow[] dataRows,
DataTableMapping tableMapping)
Parameters
• dataRows – An array of System.Data.DataRow to update from.
• tableMapping – The System.Data.IDataAdapter.TableMappings collection to use.
Returns
The number of rows successfully updated from the System.Data.DataRow array.
Usage
The Update is carried out using the InsertCommand, UpdateCommand, and DeleteCommand
on each row in the data set that has been inserted, updated, or deleted.
For more information, see Inserting, updating, and deleting rows using the SADataAdapter
object.
DeleteCommand property
Specifies an SACommand object that is executed against the database when the Update
method is called to delete rows in the database that correspond to deleted rows in the DataSet.
C# syntax
public new SACommand DeleteCommand {get;set;}
Remarks
If this property is not set and primary key information is present in the DataSet during Update,
DeleteCommand can be generated automatically by setting SelectCommand and using the
SACommandBuilder. In that case, the SACommandBuilder generates any additional
commands that you do not set. This generation logic requires key column information to be
present in the SelectCommand.
When DeleteCommand is assigned to an existing SACommand object, the SACommand
object is not cloned. The DeleteCommand maintains a reference to the existing SACommand.
InsertCommand property
Specifies an SACommand that is executed against the database when the Update method is
called that adds rows to the database to correspond to rows that were inserted in the DataSet.
C# syntax
public new SACommand InsertCommand {get;set;}
Remarks
The SACommandBuilder does not require key columns to generate InsertCommand.
When InsertCommand is assigned to an existing SACommand object, the SACommand is not
cloned. The InsertCommand maintains a reference to the existing SACommand.
If this command returns rows, the rows may be added to the DataSet depending on how you set
the UpdatedRowSource property of the SACommand object.
SelectCommand property
Specifies an SACommand that is used during Fill or FillSchema to obtain a result set from the
database for copying into a DataSet.
C# syntax
public new SACommand SelectCommand {get;set;}
Remarks
When SelectCommand is assigned to a previously-created SACommand, the SACommand is
not cloned. The SelectCommand maintains a reference to the previously-created
SACommand object.
If the SelectCommand does not return any rows, no tables are added to the DataSet, and no
exception is raised.
The SELECT statement can also be specified in the SADataAdapter constructor.
Programming 267
.NET Application Programming
TableMappings property
Specifies a collection that provides the master mapping between a source table and a
DataTable.
C# syntax
public new DataTableMappingCollection TableMappings {get;}
Remarks
The default value is an empty collection.
When reconciling changes, the SADataAdapter uses the DataTableMappingCollection
collection to associate the column names used by the data source with the column names used
by the DataSet.
The TableMappings property is not available in the .NET Compact Framework 2.0.
UpdateBatchSize property
Gets or sets the number of rows that are processed in each round-trip to the server.
C# syntax
public override int UpdateBatchSize {get;set;}
Remarks
The default value is 1.
Setting the value to something greater than 1 causes SADataAdapter.Update to execute all the
insert statements in batches. The deletions and updates are executed sequentially as before, but
insertions are executed afterward in batches of size equal to the value of UpdateBatchSize.
Setting the value to 0 causes Update to send the insert statements in a single batch.
Setting the value to something greater than 1 causes SADataAdapter.Fill to execute all the
insert statements in batches. The deletions and updates are executed sequentially as before, but
insertions are executed afterward in batches of size equal to the value of UpdateBatchSize.
Setting the value to 0 causes Fill to send the insert statements in a single batch.
Setting it less than 0 is an error.
If UpdateBatchSize is set to something other than one, and the InsertCommand property is set
to something that is not an INSERT statement, then an exception is thrown when calling Fill.
This behavior is different from SqlDataAdapter. It batches all types of commands.
UpdateCommand property
Specifies an SACommand that is executed against the database when the Update method is
called to update rows in the database that correspond to updated rows in the DataSet.
C# syntax
public new SACommand UpdateCommand {get;set;}
Remarks
During Update, if this property is not set and primary key information is present in the
SelectCommand, the UpdateCommand can be generated automatically if you set the
SelectCommand property and use the SACommandBuilder. Then, any additional commands
that you do not set are generated by the SACommandBuilder. This generation logic requires
key column information to be present in the SelectCommand.
When UpdateCommand is assigned to a previously-created SACommand, the SACommand
is not cloned. The UpdateCommand maintains a reference to the previously-created
SACommand object.
If execution of this command returns rows, these rows can be merged with the DataSet
depending on how you set the UpdatedRowSource property of the SACommand object.
RowUpdated() event
Occurs during an update after a command is executed against the data source.
C# syntax
public event SARowUpdatedEventHandler RowUpdated;
Usage
When an attempt to update is made, the event fires.
The event handler receives an argument of type SARowUpdatedEventArgs containing data
related to this event.
For more information, see the .NET Framework documentation for
OleDbDataAdapter.RowUpdated Event.
Programming 269
.NET Application Programming
RowUpdating() event
Occurs during an update before a command is executed against the data source.
C# syntax
public event SARowUpdatingEventHandler RowUpdating;
Usage
When an attempt to update is made, the event fires.
The event handler receives an argument of type SARowUpdatingEventArgs containing data
related to this event.
For more information, see the .NET Framework documentation for
OleDbDataAdapter.RowUpdating Event.
DREnumerator class
C# syntax
private sealed class DREnumerator :
System.Collections.IEnumerator
Remarks
Custom Attribute: sealed
C# syntax
public DREnumerator ( SADataReader dataReader)
MoveNext() method
C# syntax
public bool MoveNext ()
Reset() method
C# syntax
public void Reset ()
Current property
C# syntax
public object Current {get;}
SADataSourceEnumerator class
Provides a mechanism for enumerating all available instances of SQL Anywhere database
servers within the local network.
C# syntax
public sealed class SADataSourceEnumerator :
System.Data.Common.DbDataSourceEnumerator
Remarks
There is no constructor for SADataSourceEnumerator.
The SADataSourceEnumerator class is not available in the .NET Compact Framework 2.0.
Custom Attribute: sealed
Programming 271
.NET Application Programming
GetDataSources() method
Retrieves a DataTable containing information about all visible SQL Anywhere database
servers.
C# syntax
public override DataTable GetDataSources ()
Examples
The following code fills a DataTable with information for each database server that is
available.
DataTable servers =
SADataSourceEnumerator.Instance.GetDataSources();
Usage
The returned table has four columns: ServerName, IPAddress, PortNumber, and
DataBaseNames. There is a row in the table for each available database server.
Instance property
Gets an instance of SADataSourceEnumerator, which can be used to retrieve information
about all visible SQL Anywhere database servers.
C# syntax
public SADataSourceEnumerator Instance {get;}
SADefault class
Represents a parameter with a default value.
C# syntax
public sealed class SADefault
Remarks
There is no constructor for SADefault.
Value field
Gets the value for a default parameter.
C# syntax
public static readonly SADefault Value;
Remarks
This field is read-only and static.
SAError class
Collects information relevant to a warning or error returned by the data source.
C# syntax
public sealed class SAError
Remarks
There is no constructor for SAError.
For information about error handling, see Error handling and the SQL Anywhere .NET Data
Provider.
Custom Attribute: sealed
ToString() method
The complete text of the error message.
C# syntax
public override string ToString ()
Programming 273
.NET Application Programming
Examples
The return value is a string is in the form SAError:, followed by the Message. For example:
SAError:UserId or Password not valid.
Message property
Returns a short description of the error.
C# syntax
public string Message {get;}
NativeError property
Returns database-specific error information.
C# syntax
public int NativeError {get;}
Source property
Returns the name of the provider that generated the error.
C# syntax
public string Source {get;}
SqlState property
The SQL Anywhere five-character SQLSTATE following the ANSI SQL standard.
C# syntax
public string SqlState {get;}
SAErrorCollection class
Collects all errors generated by the SQL Anywhere .NET Data Provider.
C# syntax
public sealed class SAErrorCollection :
System.Collections.ICollection, System.Collections.IEnumerable
Remarks
There is no constructor for SAErrorCollection. Typically, an SAErrorCollection is obtained
from the SAException.Errors property.
Implements: ICollection, IEnumerable
For information about error handling, see Error handling and the SQL Anywhere .NET Data
Provider.
C# syntax
public void CopyTo (Array array, int index)
Parameters
• array – The array into which to copy the elements.
• index – The starting index of the array.
GetEnumerator() method
Returns an enumerator that iterates through the SAErrorCollection.
Programming 275
.NET Application Programming
C# syntax
public IEnumerator GetEnumerator ()
Returns
An System.Collections.IEnumerator for the SAErrorCollection.
Count property
Returns the number of errors in the collection.
C# syntax
public int Count {get;}
this property
Returns the error at the specified index.
C# syntax
public SAError this {get;}
Remarks
An SAError object that contains the error at the specified index.
SAException class
The exception that is thrown when SQL Anywhere returns a warning or error.
C# syntax
public class SAException : System.Exception
Remarks
There is no constructor for SAException. Typically, an SAException object is declared in a
catch. For example:
...
catch( SAException ex )
{
For information about error handling, see Error handling and the SQL Anywhere .NET Data
Provider.
C# syntax
public override void GetObjectData (SerializationInfo info,
StreamingContext context)
Parameters
• info – The SerializationInfo that holds the serialized object data about the exception being
thrown.
• context – The StreamingContext that contains contextual information about the source or
destination.
Usage
Overrides Exception.GetObjectData.
Errors property
Returns a collection of one or more SAError objects.
C# syntax
public SAErrorCollection Errors {get;}
Remarks
The SAErrorCollection object always contains at least one instance of the SAError object.
Message property
Returns the text describing the error.
Programming 277
.NET Application Programming
C# syntax
public override string Message {get;}
Remarks
This method returns a single string that contains a concatenation of all of the Message
properties of all of the SAError objects in the Errors collection. Each message, except the last
one, is followed by a carriage return.
NativeError property
Returns database-specific error information.
C# syntax
public int NativeError {get;}
Source property
Returns the name of the provider that generated the error.
C# syntax
public override string Source {get;}
SAFactory class
Represents a set of methods for creating instances of the iAnywhere.Data.SQLAnywhere
provider's implementation of the data source classes.
C# syntax
public sealed class SAFactory :
System.Data.Common.DbProviderFactory
Remarks
There is no constructor for SAFactory.
ADO.NET 2.0 adds two new classes, DbProviderFactories and DbProviderFactory, to make
provider independent code easier to write. To use them with SQL Anywhere specify
iAnywhere.Data.SQLAnywhere as the provider invariant name passed to GetFactory. For
example:
' Visual Basic
Dim factory As DbProviderFactory = _
DbProviderFactories.GetFactory( "iAnywhere.Data.SQLAnywhere" )
Dim conn As DbConnection = _
factory.CreateConnection()
// C#
DbProviderFactory factory =
DbProviderFactories.GetFactory("iAnywhere.Data.SQLAnywhere" );
DbConnection conn = factory.CreateConnection();
CreateCommand() method
Returns a strongly typed System.Data.Common.DbCommand instance.
C# syntax
public override DbCommand CreateCommand ()
Returns
A new SACommand object typed as DbCommand.
CreateCommandBuilder() method
Returns a strongly typed System.Data.Common.DbCommandBuilder instance.
C# syntax
public override DbCommandBuilder CreateCommandBuilder ()
Programming 279
.NET Application Programming
Returns
A new SACommand object typed as DbCommand.
CreateConnection() method
Returns a strongly typed System.Data.Common.DbConnection instance.
C# syntax
public override DbConnection CreateConnection ()
Returns
A new SACommand object typed as DbCommand.
CreateConnectionStringBuilder() method
Returns a strongly typed System.Data.Common.DbConnectionStringBuilder instance.
C# syntax
public override DbConnectionStringBuilder
CreateConnectionStringBuilder ()
Returns
A new SACommand object typed as DbCommand.
CreateDataAdapter() method
Returns a strongly typed System.Data.Common.DbDataAdapter instance.
C# syntax
public override DbDataAdapter CreateDataAdapter ()
Returns
A new SACommand object typed as DbCommand.
CreateDataSourceEnumerator() method
Returns a strongly typed System.Data.Common.DbDataSourceEnumerator instance.
C# syntax
public override DbDataSourceEnumerator
CreateDataSourceEnumerator ()
Returns
A new SACommand object typed as DbCommand.
CreateParameter() method
Returns a strongly typed System.Data.Common.DbParameter instance.
C# syntax
public override DbParameter CreateParameter ()
Returns
A new SACommand object typed as DbCommand.
CreatePermission(PermissionState) method
Returns a strongly-typed CodeAccessPermission instance.
C# syntax
public override CodeAccessPermission CreatePermission
(PermissionState state)
Parameters
• state – A member of the System.Security.Permissions.PermissionState enumeration.
Returns
A new SACommand object typed as DbCommand.
Programming 281
.NET Application Programming
CanCreateDataSourceEnumerator property
Always returns true, which indicates that an SADataSourceEnumerator object can be created.
C# syntax
public override bool CanCreateDataSourceEnumerator {get;}
Remarks
A new SACommand object typed as DbCommand.
Instance field
Represents the singleton instance of the SAFactory class.
C# syntax
public static readonly SAFactory Instance;
Remarks
SAFactory is a singleton class, which means only this instance of this class can exist.
Normally you would not use this field directly. Instead, you get a reference to this instance of
SAFactory using System.Data.Common.DbProviderFactories.GetFactory(String). For an
example, see the SAFactory description.
The SAFactory class is not available in the .NET Compact Framework 2.0.
SAInfoMessageEventArgs class
Provides data for the InfoMessage event.
C# syntax
public sealed class SAInfoMessageEventArgs : System.EventArgs
Remarks
There is no constructor for SAInfoMessageEventArgs.
Custom Attribute: sealed
ToString() method
Retrieves a string representation of the InfoMessage event.
C# syntax
public override string ToString ()
Returns
A string representing the InfoMessage event.
Errors property
Returns the collection of messages sent from the data source.
C# syntax
public SAErrorCollection Errors {get;}
Message property
Returns the full text of the error sent from the data source.
C# syntax
public string Message {get;}
MessageType property
Returns the type of the message.
C# syntax
public SAMessageType MessageType {get;}
Programming 283
.NET Application Programming
Remarks
This can be one of: Action, Info, Status, or Warning.
NativeError property
Returns the SQLCODE returned by the database.
C# syntax
public int NativeError {get;}
Source property
Returns the name of the SQL Anywhere .NET Data Provider.
C# syntax
public string Source {get;}
SAMetaDataCollectionNames class
Provides a list of constants for use with the SAConnection.GetSchema(string) method to
retrieve metadata collections.
C# syntax
public sealed class SAMetaDataCollectionNames
Remarks
This field is constant and read-only.
Columns field
Provides a constant for use with the SAConnection.GetSchema(string) method that represents
the Columns collection.
C# syntax
public static readonly string Columns;
The following code fills a DataTable with the Columns collection.
DataTable schema =
GetSchema( SAMetaDataCollectionNames.Columns );
DataSourceInformation field
Provides a constant for use with the SAConnection.GetSchema(string) method that represents
the DataSourceInformation collection.
C# syntax
public static readonly string DataSourceInformation;
The following code fills a DataTable with the DataSourceInformation collection.
DataTable schema =
GetSchema( SAMetaDataCollectionNames.DataSourceInformation );
DataTypes field
Provides a constant for use with the SAConnection.GetSchema(string) method that represents
the DataTypes collection.
C# syntax
public static readonly string DataTypes;
The following code fills a DataTable with the DataTypes collection.
DataTable schema =
GetSchema( SAMetaDataCollectionNames.DataTypes );
ForeignKeys field
Provides a constant for use with the SAConnection.GetSchema(string) method that represents
the ForeignKeys collection.
C# syntax
public static readonly string ForeignKeys;
Programming 285
.NET Application Programming
IndexColumns field
Provides a constant for use with the SAConnection.GetSchema(string) method that represents
the IndexColumns collection.
C# syntax
public static readonly string IndexColumns;
The following code fills a DataTable with the IndexColumns collection.
DataTable schema =
GetSchema( SAMetaDataCollectionNames.IndexColumns );
Indexes field
Provides a constant for use with the SAConnection.GetSchema(string) method that represents
the Indexes collection.
C# syntax
public static readonly string Indexes;
The following code fills a DataTable with the Indexes collection.
DataTable schema =
GetSchema( SAMetaDataCollectionNames.Indexes );
MetaDataCollections field
Provides a constant for use with the SAConnection.GetSchema(string) method that represents
the MetaDataCollections collection.
C# syntax
public static readonly string MetaDataCollections;
The following code fills a DataTable with the MetaDataCollections collection.
DataTable schema =
GetSchema( SAMetaDataCollectionNames.MetaDataCollections );
ProcedureParameters field
Provides a constant for use with the SAConnection.GetSchema(string) method that represents
the ProcedureParameters collection.
C# syntax
public static readonly string ProcedureParameters;
The following code fills a DataTable with the ProcedureParameters collection.
DataTable schema =
GetSchema( SAMetaDataCollectionNames.ProcedureParameters );
Procedures field
Provides a constant for use with the SAConnection.GetSchema(string) method that represents
the Procedures collection.
C# syntax
public static readonly string Procedures;
The following code fills a DataTable with the Procedures collection.
DataTable schema =
GetSchema( SAMetaDataCollectionNames.Procedures );
ReservedWords field
Provides a constant for use with the SAConnection.GetSchema(string) method that represents
the ReservedWords collection.
C# syntax
public static readonly string ReservedWords;
The following code fills a DataTable with the ReservedWords collection.
DataTable schema =
GetSchema( SAMetaDataCollectionNames.ReservedWords );
Programming 287
.NET Application Programming
Restrictions field
Provides a constant for use with the SAConnection.GetSchema(string) method that represents
the Restrictions collection.
C# syntax
public static readonly string Restrictions;
The following code fills a DataTable with the Restrictions collection.
DataTable schema =
GetSchema( SAMetaDataCollectionNames.Restrictions );
Tables field
Provides a constant for use with the SAConnection.GetSchema(string) method that represents
the Tables collection.
C# syntax
public static readonly string Tables;
The following code fills a DataTable with the Tables collection.
DataTable schema =
GetSchema( SAMetaDataCollectionNames.Tables );
UserDefinedTypes field
Provides a constant for use with the SAConnection.GetSchema(string) method that represents
the UserDefinedTypes collection.
C# syntax
public static readonly string UserDefinedTypes;
The following code fills a DataTable with the UserDefinedTypes collection.
DataTable schema =
GetSchema( SAMetaDataCollectionNames.UserDefinedTypes );
Users field
Provides a constant for use with the SAConnection.GetSchema(string) method that represents
the Users collection.
C# syntax
public static readonly string Users;
The following code fills a DataTable with the Users collection.
DataTable schema =
GetSchema( SAMetaDataCollectionNames.Users );
ViewColumns field
Provides a constant for use with the SAConnection.GetSchema(string) method that represents
the ViewColumns collection.
C# syntax
public static readonly string ViewColumns;
The following code fills a DataTable with the ViewColumns collection.
DataTable schema =
GetSchema( SAMetaDataCollectionNames.ViewColumns );
Views field
Provides a constant for use with the SAConnection.GetSchema(string) method that represents
the Views collection.
C# syntax
public static readonly string Views;
The following code fills a DataTable with the Views collection.
DataTable schema =
GetSchema( SAMetaDataCollectionNames.Views );
Programming 289
.NET Application Programming
SAParameter class
Represents a parameter to an SACommand, and optionally, its mapping to a DataSet column.
C# syntax
public sealed class SAParameter :
System.Data.Common.DbParameter, System.ICloneable
Remarks
Implements: IDbDataParameter, IDataParameter, ICloneable
Custom Attribute: sealed
ResetDbType() method
Resets the type (the values of DbType and SADbType) associated with this SAParameter.
C# syntax
public override void ResetDbType ()
ToString() method
Returns a string containing the ParameterName.
C# syntax
public override string ToString ()
Returns
The name of the parameter.
DbType property
Gets and sets the DbType of the parameter.
C# syntax
public override DbType DbType {get;set;}
Remarks
The SADbType and DbType are linked. Therefore, setting the DbType changes the
SADbType to a supporting SADbType.
The value must be a member of the SADbType enumerator.
Direction property
Gets and sets a value indicating whether the parameter is input-only, output-only,
bidirectional, or a stored procedure return value parameter.
C# syntax
public override ParameterDirection Direction {get;set;}
Remarks
One of the ParameterDirection values.
If the ParameterDirection is output, and execution of the associated SACommand does not
return a value, the SAParameter contains a null value. After the last row from the last result set
is read, the Output, InputOut, and ReturnValue parameters are updated.
IsNullable property
Gets and sets a value indicating whether the parameter accepts null values.
C# syntax
public override bool IsNullable {get;set;}
Remarks
This property is true if null values are accepted; otherwise, it is false. The default is false. Null
values are handled using the DBNull class.
Offset property
Gets and sets the offset to the Value property.
Programming 291
.NET Application Programming
C# syntax
public int Offset {get;set;}
Remarks
The offset to the value. The default is 0.
ParameterName property
Gets and sets the name of the SAParameter.
C# syntax
public override string ParameterName {get;set;}
Remarks
The default is an empty string.
The SQL Anywhere .NET Data Provider uses positional parameters that are marked with a
question mark (?) instead of named parameters.
Precision property
Gets and sets the maximum number of digits used to represent the Value property.
C# syntax
public byte Precision {get;set;}
Remarks
The value of this property is the maximum number of digits used to represent the Value
property. The default value is 0, which indicates that the data provider sets the precision for the
Value property.
The Precision property is only used for decimal and numeric input parameters.
SADbType property
The SADbType of the parameter.
C# syntax
public SADbType SADbType {get;set;}
Remarks
The SADbType and DbType are linked. Therefore, setting the SADbType changes the
DbType to a supporting DbType.
The value must be a member of the SADbType enumerator.
Scale property
Gets and sets the number of decimal places to which Value is resolved.
C# syntax
public byte Scale {get;set;}
Remarks
The number of decimal places to which Value is resolved. The default is 0.
The Scale property is only used for decimal and numeric input parameters.
Size property
Gets and sets the maximum size, in bytes, of the data within the column.
C# syntax
public override int Size {get;set;}
Remarks
The value of this property is the maximum size, in bytes, of the data within the column. The
default value is inferred from the parameter value.
The value of this property is the maximum size, in bytes, of the data within the column. The
default value is inferred from the parameter value.
The Size property is used for binary and string types.
For variable length data types, the Size property describes the maximum amount of data to
transmit to the server. For example, the Size property can be used to limit the amount of data
sent to the server for a string value to the first one hundred bytes.
Programming 293
.NET Application Programming
If not explicitly set, the size is inferred from the actual size of the specified parameter value.
For fixed width data types, the value of Size is ignored. It can be retrieved for informational
purposes, and returns the maximum amount of bytes the provider uses when transmitting the
value of the parameter to the server.
SourceColumn property
Gets and sets the name of the source column mapped to the DataSet and used for loading or
returning the value.
C# syntax
public override string SourceColumn {get;set;}
Remarks
A string specifying the name of the source column mapped to the DataSet and used for loading
or returning the value.
When SourceColumn is set to anything other than an empty string, the value of the parameter
is retrieved from the column with the SourceColumn name. If Direction is set to Input, the
value is taken from the DataSet. If Direction is set to Output, the value is taken from the data
source. A Direction of InputOutput is a combination of both.
SourceColumnNullMapping property
Gets and sets value that indicates whether the source column is nullable.
C# syntax
public override bool SourceColumnNullMapping {get;set;}
Remarks
This allows SACommandBuilder to generate Update statements for nullable columns
correctly.
If the source column is nullable, true is returned; otherwise, false.
SourceVersion property
Gets and sets the DataRowVersion to use when loading Value.
C# syntax
public override DataRowVersion SourceVersion {get;set;}
Remarks
Used by UpdateCommand during an Update operation to determine whether the parameter
value is set to Current or Original. This allows primary keys to be updated. This property is
ignored by InsertCommand and DeleteCommand. This property is set to the version of the
DataRow used by the Item property, or the GetChildRows method of the DataRow object.
Value property
Gets and sets the value of the parameter.
C# syntax
public override object Value {get;set;}
Remarks
An Object that specifies the value of the parameter.
For input parameters, the value is bound to the SACommand that is sent to the server. For
output and return value parameters, the value is set on completion of the SACommand and
after the SADataReader is closed.
When sending a null parameter value to the server, you must specify DBNull, not null. The
null value in the system is an empty object that has no value. DBNull is used to represent null
values.
If the application specifies the database type, the bound value is converted to that type when
the SQL Anywhere .NET Data Provider sends the data to the server. The provider attempts to
convert any type of value if it supports the IConvertible interface. Conversion errors may result
if the specified type is not compatible with the value.
Both the DbType and SADbType properties can be inferred by setting the Value.
The Value property is overwritten by Update.
SAParameterCollection class
Represents all parameters to an SACommand object and, optionally, their mapping to a
DataSet column.
Programming 295
.NET Application Programming
C# syntax
public sealed class SAParameterCollection :
System.Data.Common.DbParameterCollection
Remarks
There is no constructor for SAParameterCollection. You obtain an SAParameterCollection
object from the SACommand.Parameters property of an SACommand object.
SADBParametersEditor class
C# syntax
private class SADBParametersEditor : CollectionEditor
SADBParametersEditor(Type) constructor
C# syntax
public SADBParametersEditor (Type type)
CanSelectMultipleInstances() method
C# syntax
protected override bool CanSelectMultipleInstances ()
CreateInstance(Type) method
C# syntax
protected override object CreateInstance (Type type)
C# syntax
public override object EditValue (ITypeDescriptorContext
context, IServiceProvider provider, object value)
GetEditStyle(ITypeDescriptorContext) method
C# syntax
public override UITypeEditorEditStyle GetEditStyle
(ITypeDescriptorContext context)
C# syntax
public SAParameter AddWithValue (string parameterName, object
value)
Parameters
• parameterName – The name of the parameter.
• value – The value to be added.
Returns
The new SAParameter object.
Programming 297
.NET Application Programming
Clear() method
Removes all items from the collection.
C# syntax
public override void Clear ()
C# syntax
public override void CopyTo (Array array, int index)
Parameters
• array – The array to copy the SAParameter objects into.
• index – The starting index of the array.
GetEnumerator() method
Returns an enumerator that iterates through the SAParameterCollection.
C# syntax
public override IEnumerator GetEnumerator ()
Returns
An System.Collections.IEnumerator for the SAParameterCollection object.
C# syntax
public override void Insert (int index, object value)
Parameters
• index – The zero-based index where the parameter is to be inserted within the collection.
• value – The SAParameter object to add to the collection.
Remove(object) method
Removes the specified SAParameter object from the collection.
C# syntax
public override void Remove (object value)
Parameters
• value – The SAParameter object to remove from the collection.
Count property
Returns the number of SAParameter objects in the collection.
C# syntax
public override int Count {get;}
Remarks
The number of SAParameter objects in the collection.
IsFixedSize property
Gets a value that indicates whether the SAParameterCollection has a fixed size.
C# syntax
public override bool IsFixedSize {get;}
Remarks
True if this collection has a fixed size, false otherwise.
Programming 299
.NET Application Programming
IsReadOnly property
Gets a value that indicates whether the SAParameterCollection is read-only.
C# syntax
public override bool IsReadOnly {get;}
Remarks
True if this collection is read-only, false otherwise.
IsSynchronized property
Gets a value that indicates whether the SAParameterCollection object is synchronized.
C# syntax
public override bool IsSynchronized {get;}
Remarks
True if this collection is synchronized, false otherwise.
SyncRoot property
Gets an object that can be used to synchronize access to the SAParameterCollection.
C# syntax
public override object SyncRoot {get;}
this property
Gets and sets the SAParameter object at the specified index.
C# syntax
public new SAParameter this {get;set;}
Remarks
An SAParameter object.
In C#, this property is the indexer for the SAParameterCollection object.
An SAParameter object.
In C#, this property is the indexer for the SAParameterCollection object.
SADBParametersEditor class
C# syntax
private class SADBParametersEditor : CollectionEditor
SADBParametersEditor(Type) constructor
C# syntax
public SADBParametersEditor (Type type)
CanSelectMultipleInstances() method
C# syntax
protected override bool CanSelectMultipleInstances ()
CreateInstance(Type) method
C# syntax
protected override object CreateInstance (Type type)
Programming 301
.NET Application Programming
C# syntax
public override object EditValue (ITypeDescriptorContext
context, IServiceProvider provider, object value)
GetEditStyle(ITypeDescriptorContext) method
C# syntax
public override UITypeEditorEditStyle GetEditStyle
(ITypeDescriptorContext context)
SAPermission class
Enables the SQL Anywhere .NET Data Provider to ensure that a user has a security level
adequate to access a SQL Anywhere data source.
C# syntax
public sealed class SAPermission :
System.Data.Common.DBDataPermission
Remarks
Custom Attribute: sealed
SAPermission(PermissionState) constructor
Initializes a new instance of the SAPermission class.
C# syntax
public SAPermission (PermissionState state)
Parameters
• state – One of the PermissionState values.
CreateInstance() method
Creates a new instance of an SAPermission class.
C# syntax
protected override DBDataPermission CreateInstance ()
Returns
A new SAPermission object.
SAPermissionAttribute class
Associates a security action with a custom security attribute.
C# syntax
public sealed class SAPermissionAttribute :
System.Data.Common.DBDataPermissionAttribute
Remarks
Custom Attribute: sealed
SAPermissionAttribute(SecurityAction) constructor
Initializes a new instance of the SAPermissionAttribute class.
C# syntax
public SAPermissionAttribute (SecurityAction action)
Programming 303
.NET Application Programming
Parameters
• action – One of the SecurityAction values representing an action that can be performed
using declarative security.
Returns
An SAPermissionAttribute object.
CreatePermission() method
Returns an SAPermission object that is configured according to the attribute properties.
C# syntax
public override IPermission CreatePermission ()
SARowUpdatedEventArgs class
Provides data for the RowUpdated event.
C# syntax
public sealed class SARowUpdatedEventArgs :
System.Data.Common.RowUpdatedEventArgs
Remarks
Custom Attribute: sealed
C# syntax
public SARowUpdatedEventArgs (DataRow row, IDbCommand command,
StatementType statementType, DataTableMapping tableMapping)
Parameters
• row – The DataRow sent through an Update.
• command – The IDbCommand executed when Update is called.
• statementType – One of the StatementType values that specifies the type of query
executed.
• tableMapping – The DataTableMapping sent through an Update.
Command property
Gets the SACommand that is executed when DataAdapter.Update is called.
C# syntax
public new SACommand Command {get;}
RecordsAffected property
Returns the number of rows changed, inserted, or deleted by execution of the SQL statement.
C# syntax
public new int RecordsAffected {get;}
Remarks
The number of rows changed, inserted, or deleted; 0 if no rows were affected or the statement
failed; and -1 for SELECT statements.
SARowUpdatingEventArgs class
Provides data for the RowUpdating event.
C# syntax
public sealed class SARowUpdatingEventArgs :
System.Data.Common.RowUpdatingEventArgs
Remarks
Custom Attribute: sealed
Programming 305
.NET Application Programming
C# syntax
public SARowUpdatingEventArgs (DataRow row, IDbCommand
command, StatementType statementType, DataTableMapping
tableMapping)
Parameters
• row – The DataRow to update.
• command – The IDbCommand to execute during update.
• statementType – One of the StatementType values that specifies the type of query
executed.
• tableMapping – The DataTableMapping sent through an Update.
Command property
Specifies the SACommand to execute when performing the Update.
C# syntax
public new SACommand Command {get;set;}
SARowsCopiedEventArgs class
Represents the set of arguments passed to the SARowsCopiedEventHandler.
C# syntax
public sealed class SARowsCopiedEventArgs
Remarks
The SARowsCopiedEventArgs class is not available in the .NET Compact Framework 2.0.
Custom Attribute: sealed
SARowsCopiedEventArgs(long) constructor
Creates a new instance of the SARowsCopiedEventArgs object.
C# syntax
public SARowsCopiedEventArgs (long rowsCopied)
Parameters
• rowsCopied – An 64-bit integer value that indicates the number of rows copied during the
current bulk-copy operation.
Usage
The SARowsCopiedEventArgs class is not available in the .NET Compact Framework 2.0.
Abort property
Gets or sets a value that indicates whether the bulk-copy operation should be aborted.
C# syntax
public bool Abort {get;set;}
Remarks
The SARowsCopiedEventArgs class is not available in the .NET Compact Framework 2.0.
RowsCopied property
Gets the number of rows copied during the current bulk-copy operation.
C# syntax
public long RowsCopied {get;}
Remarks
The SARowsCopiedEventArgs class is not available in the .NET Compact Framework 2.0.
Programming 307
.NET Application Programming
SATcpOptionsBuilder class
Provides a simple way to create and manage the TCP options portion of connection strings
used by the SAConnection object.
C# syntax
public sealed class SATcpOptionsBuilder :
SAConnectionStringBuilderBase
Remarks
The SATcpOptionsBuilder class is not available in the .NET Compact Framework 2.0.
ContainsKey(string) method
Determines whether the SAConnectionStringBuilder object contains a specific keyword.
C# syntax
public override bool ContainsKey (string keyword)
Parameters
• keyword – The keyword to locate in the SAConnectionStringBuilder.
Returns
True if the value associated with keyword has been set; otherwise, false.
Examples
The following statement determines whether the SAConnectionStringBuilder object contains
the UserID keyword.
connectString.ContainsKey("UserID")
GetUseLongNameAsKeyword() method
Gets a boolean values that indicates whether long connection parameter names are used in the
connection string.
C# syntax
public bool GetUseLongNameAsKeyword ()
Returns
True if long connection parameter names are used to build connection strings; otherwise,
false.
Usage
SQL Anywhere connection parameters have both long and short forms of their names. For
example, to specify the name of an ODBC data source in your connection string, you can use
either of the following values: DataSourceName or DSN. By default, long connection
parameter names are used to build connection strings.
Remove(string) method
Removes the entry with the specified key from the SAConnectionStringBuilder instance.
C# syntax
public override bool Remove (string keyword)
Parameters
• keyword – The key of the key/value pair to be removed from the connection string in this
SAConnectionStringBuilder.
Returns
True if the key existed within the connection string and was removed; false if the key did not
exist.
Programming 309
.NET Application Programming
SetUseLongNameAsKeyword(bool) method
Sets a boolean value that indicates whether long connection parameter names are used in the
connection string.
C# syntax
public void SetUseLongNameAsKeyword (bool useLongNameAsKeyword)
Parameters
• useLongNameAsKeyword – A boolean value that indicates whether the long connection
parameter name is used in the connection string.
Usage
Long connection parameter names are used by default.
ShouldSerialize(string) method
Indicates whether the specified key exists in this SAConnectionStringBuilder instance.
C# syntax
public override bool ShouldSerialize (string keyword)
Parameters
• keyword – The key to locate in the SAConnectionStringBuilder.
Returns
True if the SAConnectionStringBuilder contains an entry with the specified key; otherwise
false.
ToString() method
Converts the SATcpOptionsBuilder object to a string representation.
C# syntax
public override string ToString ()
Returns
The options string being built.
C# syntax
public override bool TryGetValue (string keyword, out object
value)
Parameters
• keyword – The key of the item to retrieve.
• value – The value corresponding to keyword.
Returns
true if keyword was found within the connection string; otherwise false.
Broadcast property
Gets or sets the Broadcast option.
C# syntax
public string Broadcast {get;set;}
BroadcastListener property
Gets or sets the BroadcastListener option.
C# syntax
public string BroadcastListener {get;set;}
Programming 311
.NET Application Programming
ClientPort property
Gets or sets the ClientPort option.
C# syntax
public string ClientPort {get;set;}
DoBroadcast property
Gets or sets the DoBroadcast option.
C# syntax
public string DoBroadcast {get;set;}
Host property
Gets or sets the Host option.
C# syntax
public string Host {get;set;}
IPV6 property
Gets or sets the IPV6 option.
C# syntax
public string IPV6 {get;set;}
Keys property
Gets an System.Collections.ICollection that contains the keys in the
SAConnectionStringBuilder.
C# syntax
public override ICollection Keys {get;}
Remarks
An System.Collections.ICollection that contains the keys in the SAConnectionStringBuilder.
LDAP property
Gets or sets the LDAP option.
C# syntax
public string LDAP {get;set;}
LocalOnly property
Gets or sets the LocalOnly option.
C# syntax
public string LocalOnly {get;set;}
MyIP property
Gets or sets the MyIP option.
C# syntax
public string MyIP {get;set;}
ReceiveBufferSize property
Gets or sets the ReceiveBufferSize option.
C# syntax
public int ReceiveBufferSize {get;set;}
Programming 313
.NET Application Programming
SendBufferSize property
Gets or sets the Send BufferSize option.
C# syntax
public int SendBufferSize {get;set;}
ServerPort property
Gets or sets the ServerPort option.
C# syntax
public string ServerPort {get;set;}
TDS property
Gets or sets the TDS option.
C# syntax
public string TDS {get;set;}
this property
Gets or sets the value of the connection keyword.
C# syntax
public override object this {get;set;}
Remarks
An object representing the value of the specified connection keyword.
If the keyword or type is invalid, an exception is raised. keyword is case insensitive.
When setting the value, passing NULL clears the value.
Timeout property
Gets or sets the Timeout option.
C# syntax
public int Timeout {get;set;}
VerifyServerName property
Gets or sets the VerifyServerName option.
C# syntax
public string VerifyServerName {get;set;}
SATransaction class
Represents a SQL transaction.
C# syntax
public sealed class SATransaction :
System.Data.Common.DbTransaction
Remarks
There is no constructor for SATransaction. To obtain an SATransaction object, use one of the
BeginTransaction methods. To associate a command with a transaction, use the
SACommand.Transaction property.
For more information, see Transaction processing and Inserting, updating, and deleting rows
using the SACommand object.
Programming 315
.NET Application Programming
Commit() method
Commits the database transaction.
C# syntax
public override void Commit ()
Save(string) method
Creates a savepoint in the transaction that can be used to roll back a portion of the transaction,
and specifies the savepoint name.
C# syntax
public void Save (string savePoint)
Parameters
• savePoint – The name of the savepoint to which to roll back.
Connection property
The SAConnection object associated with the transaction, or a null reference (Nothing in
Visual Basic) if the transaction is no longer valid.
C# syntax
public new SAConnection Connection {get;}
Remarks
A single application can have multiple database connections, each with zero or more
transactions. This property enables you to determine the connection object associated with a
particular transaction created by BeginTransaction.
DbConnection property
Specifies the System.Data.Common.DbConnection object associated with the transaction.
C# syntax
protected override DbConnection DbConnection {get;}
Remarks
The System.Data.Common.DbConnection object associated with the transaction.
IsolationLevel property
Specifies the isolation level for this transaction.
C# syntax
public override System.Data.IsolationLevel IsolationLevel
{get;}
Remarks
The IsolationLevel for this transaction. This can be one of:
• Unspecified
• Chaos
• ReadUncommitted
• ReadCommitted
• RepeatableRead
• Serializable
• Snapshot
The default is ReadCommitted.
SAIsolationLevel property
Specifies the extended isolation level for this transaction.
C# syntax
public SAIsolationLevel SAIsolationLevel {get;}
Remarks
The SAIsolationLevel for this transaction. This can be one of:
Programming 317
.NET Application Programming
• Unspecified
• Chaos
• ReadUncommitted
• ReadCommitted
• RepeatableRead
• Serializable
• Snapshot
• StatementSnapshot
• ReadOnlySnapshot
The default is ReadCommitted.
Parallel transactions are not supported. Therefore, the SAIsolationLevel applies to the entire
transaction.
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.
SAP Sybase IQ includes an OLE DB provider named SAOLEDB. This provider is available for
current Windows platforms. The provider is not available for Windows Mobile platforms.
You can also access SAP Sybase IQ using the Microsoft OLE DB Provider for ODBC
(MSDASQL), together with the SQL Anywhere ODBC driver.
Using the SAP Sybase IQOLE 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 SAP Sybase IQ OLE DB provider, ODBC is not required in your
deployment.
• MSDASQL allows OLE DB clients to work with any ODBC driver, but does not guarantee
that you can use the full range of functionality of each ODBC driver. Using the SAP
Sybase IQprovider, you can get full access to SAP Sybase IQ features from OLE DB
programming environments.
Programming 319
OLE DB and ADO Development
SAP Sybase IQ OLE DB support differs from SQL Anywhere support. SAP Sybase IQ
supports Dynamic (dynamic scroll), Static (insensitive) and Forward only (no–scroll) cursors,
but does not support Keyset (scroll) cursors. In SAP Sybase IQ the isolation level is always 3,
no matter what you specify.
SAP Sybase IQ supports Dynamic (dynamic scroll), Static (insensitive) and Forward only
(no–scroll) cursors, but does not support Keyset (scroll) cursors. In SAP Sybase IQ the
isolation level is always 3, no matter what you specify.
SAP Sybase IQ does not support Windows CE or remote updates through a cursor.
Additional Information
Programming > OLE DB and ADO Development > OLE DB Connection Parameters
Supported Platforms
The SAP Sybase IQ OLE DB provider is designed to work with Microsoft Data Access
Components (MDAC) 2.8 and later versions.
Sample Code
You can try this routine by placing a command button named cmdTestConnection on a form,
and pasting the routine into its Click event. Run the program and click the button to connect
and then disconnect.
Private Sub cmdTestConnection_Click( _
ByVal eventSender As System.Object, _
ByVal eventArgs As System.EventArgs) _
Handles cmdTestConnection.Click
HandleError:
MsgBox(ErrorToString(Err.Number))
Exit Sub
End Sub
Notes
The sample carries out the following tasks:
• It declares the variables used in the routine.
• It establishes a connection, using the SAP Sybase IQ OLE DB provider, to the sample
database.
• It uses a Command object to execute a simple statement, which displays a message in the
database server messages window.
• It closes the connection.
Programming 321
OLE DB and ADO Development
Sample Code
You can try this routine by placing a command button named cmdUpdate on a form, and
pasting the routine into its Click event. Run the program and click the button to connect,
display a message in the database server messages window, and then disconnect.
Private Sub cmdUpdate_Click( _
ByVal eventSender As System.Object, _
ByVal eventArgs As System.EventArgs) _
Handles cmdUpdate.Click
'Execute a command
myCommand.CommandText = _
"UPDATE Customers SET GivenName='Liz' WHERE ID=102"
myCommand.ActiveConnection = myConn
myCommand.Execute(cAffected)
MsgBox(CStr(cAffected) & " rows affected.", _
MsgBoxStyle.Information)
myConn.Close()
Exit Sub
HandleError:
MsgBox(ErrorToString(Err.Number))
Exit Sub
End Sub
Notes
After establishing a connection, the example code creates a Command object, sets its
CommandText property to an update statement, and sets its ActiveConnection property to the
current connection. It then executes the update statement and displays the number of rows
affected by the update in a window.
In this example, the update is sent to the database and committed when it is executed.
You can also perform updates through a cursor.
Sample code
You can try this routine by placing a command button named cmdQuery on a form and pasting
the routine into its Click event. Run the program and click the button to connect, display a
message in the database server messages window, execute a query and display the first few
rows in windows, and then disconnect.
Private Sub cmdQuery_Click( _
ByVal eventSender As System.Object, _
ByVal eventArgs As System.EventArgs) _
Handles cmdQuery.Click
'Execute a query
myRS = New ADODB.Recordset
myRS.CacheSize = 50
myRS.let_Source("SELECT * FROM Customers")
myRS.let_ActiveConnection(myConn)
myRS.CursorType = ADODB.CursorTypeEnum.adOpenKeyset
myRS.LockType = ADODB.LockTypeEnum.adLockOptimistic
myRS.Open()
Programming 323
OLE DB and ADO Development
myRS.Close()
myConn.Close()
Exit Sub
ErrorHandler:
MsgBox(ErrorToString(Err.Number))
Exit Sub
End Sub
Notes
The Recordset object in this example holds the results from a query on the Customers table.
The For loop scrolls through the first several rows and displays the CompanyName value for
each row.
This is a simple example of using a cursor from ADO.
Cursor types
ADO has its own naming convention for cursor types.
The available cursor types, the corresponding cursor type constants, and the SQL Anywhere
types they are equivalent to, are as follows:
ADO cursor type ADO constant SAP Sybase IQ type
Dynamic cursor adOpenDynamic Dynamic scroll cursor
Sample code
The following code sets the cursor type for an ADO Recordset object:
Dim myRS As New ADODB.Recordset
myRS.CursorType = ADODB.CursorTypeEnum.adOpenDynamic
' Connect
myConn.Provider = "SAOLEDB"
myConn.ConnectionString = _
"Data Source=Sybase IQ Demo"
myConn.Open()
myConn.BeginTrans()
SQLString = "SELECT * FROM Customers"
myRS.Open(SQLString, myConn, _
ADODB.CursorTypeEnum.adOpenDynamic, _
ADODB.LockTypeEnum.adLockBatchOptimistic)
HandleError:
Programming 325
OLE DB and ADO Development
MsgBox(ErrorToString(Err.Number))
Exit Sub
End Sub
Notes
If you use the adLockBatchOptimistic setting on the Recordset, the myRS.Update method
does not make any changes to the database itself. Instead, it updates a local copy of the
Recordset.
The myRS.UpdateBatch method makes the update to the database server, but does not commit
it, because it is inside a transaction. If an UpdateBatch method was invoked outside a
transaction, the change would be committed.
The myConn.CommitTrans method commits the changes. The Recordset object has been
closed by this time, so there is no issue of whether the local copy of the data is changed or
not.
ADO Transactions
By default, any change you make to the database using ADO is committed when it is executed.
This includes explicit updates, and 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.
The transaction isolation level is set as a property of the Connection object. The IsolationLevel
property can take on one of the following values:
ADO isolation level Constant SAP Sybase IQ level
Unspecified adXactUnspecified Not applicable. Set to 0
Chaos adXactChaos Unsupported. Set to 0
Browse adXactBrowse 0
Read uncommitted adXactReadUncommitted 0
Cursor stability adXactCursorStability 1
Read committed adXactReadCommitted 1
Repeatable read adXactRepeatableRead 2
Isolated adXactIsolated 3
Serializable adXactSerializable 3
Snapshot 2097152 4
Statement snapshot 4194304 5
Readonly statement snapshot 8388608 6
Below are the OLE DB connection parameters that are supported by the provider. In some
cases, OLE DB connection parameters are identical to (for example, Password) or resemble
(for example, User ID) SAP Sybase IQ connection parameters. Note the use of spaces in many
of these connection parameters.
• Provider – This parameter is used to identify the SQL Anywhere OLE DB provider
(SAOLEDB).
• User ID – This connection parameter maps directly to the SAP Sybase IQ UserID (UID)
connection parameter.
• Password – This connection parameter maps directly to the SAP Sybase IQ Password
(PWD) connection parameter.
• Data Source – This connection parameter maps directly to the SAP Sybase IQ
DataSourceName (DSN) connection parameter. For example: Data Source=Sybase
IQ Demo.
• Initial Catalog – This connection parameter maps directly to the SAP Sybase IQ
DatabaseName (DBN) connection parameter. For example: Initial
Catalog=demo.
• Location – This connection parameter maps directly to the SAP Sybase IQ Host
connection parameter. The parameter value has the same form as the Host parameter value.
For example: Location=localhost:4444.
• Extended Properties – This connection parameter is used by OLE DB to pass in all the
SAP Sybase IQ specific connection parameters. For example: Extended
Properties="UserID=DBA;DBKEY=V3moj3952B;DBF=demo.db".
ADO uses this connection parameter to collect and pass in all the connection parameters
that it does not recognize.
Some Microsoft connection windows have a field called Prov String or Provider String.
The contents of this field are passed as the value to Extended Properties.
• OLE DB Services – This connection parameter is not directly handled by the SAP Sybase
IQ OLE DB provider. It controls connection pooling in ADO.
• Prompt – This connection parameter governs how a connection attempt handles errors.
The possible prompt values are 1, 2, 3, or 4. The meanings are DBPROMPT_PROMPT
(1), DBPROMPT_COMPLETE (2), DBPROMPT_COMPLETEREQUIRED (3), and
DBPROMPT_NOPROMPT (4).
Programming 327
OLE DB and ADO Development
The default prompt value is 4 which means the provider does not present a connect
window. Setting the prompt value to 1 causes a connect window to always appear. Setting
the prompt value to 2 causes a connect window to appear if the initial connection attempt
fails. Setting the prompt value to 3 causes a connect window to appear if the initial
connection attempt fails but the provider disables the controls for any information not
required to connect to the data source.
• Window Handle – The application can pass the handle of the parent window, if
applicable, or a null pointer if either the window handle is not applicable or the provider
does present any windows. The window handle value is typically 0 (NULL).
Other OLE DB connection parameters can be specified but they are ignored by the OLE DB
provider.
When the SAP Sybase IQ OLE DB provider is invoked, it gets the property values for the OLE
DB connection parameters. Here is a typical set of property values obtained from Microsoft's
RowsetViewer application.
User ID '<user_id>'
Password '<password>'
Location 'localhost:4444'
Initial Catalog 'demo'
Data Source 'testds'
Extended Properties 'appinfo=api=oledb'
Prompt 2
Window Handle 0
The connection string that the provider constructs from this set of parameter values is:
'DSN=testds;HOST=localhost:
4444;DBN=demo;UID=<user_id>;PWD=<password>;appinfo=api=oledb'
The SAP Sybase IQ OLE DB provider uses the connection string, Window Handle, and
Prompt values as parameters to the database server connection call that it makes.
This is a simple ADO connection string example.
connection.Open
"Provider=SAOLEDB;UserID=<user_id>;Location=localhost:
4444;Pwd=<password>"
ADO parses the connection string and passes all of the unrecognized connection parameters in
Extended Properties. When the SAP Sybase IQ OLE DB provider is invoked, it gets the
property values for the OLE DB connection parameters. Here is the set of property values
obtained from the ADO application that used the connection string shown above.
User ID ''
Password ''
Location 'localhost:4444'
Initial Catalog ''
Data Source ''
Extended Properties 'UserID=<user_id>;Pwd=<password>'
Prompt 4
Window Handle 0
The connection string that the provider constructs from this set of parameter values is:
'HOST=localhost:4444; UserID=<user_id>;Pwd=<password>'
The provider uses the connection string, Window Handle, and Prompt values as parameters to
the database server connection call that it makes.
If you specify OLE DB Services=-4 in your connection string, then connection pooling
and transaction enlistment are disabled. Here is a sample connection string:
Provider=SAOLEDB;OLE DB Services=-4;...
In this example, SADATABASE is the name of the Linked Server, demo is the catalog or
database name, GROUPO is the table owner in the SAP Sybase IQ database, and Customers
is the table name in the SAP Sybase IQ database.
Programming 329
OLE DB and ADO Development
Instead of returning one row in the result set to SQL Server, all rows are returned and then this
result set is reduced to one row by SQL Server. The following example produces an identical
result but only one row is returned to SQL Server.
SELECT * FROM OPENQUERY( SADATABASE,
'SELECT ID, Surname, GivenName FROM [GROUPO].[Customers]
WHERE Surname = ''Elkins''' )
You can set up a Linked Server that uses the SAP Sybase IQ OLE DB provider using a
Microsoft SQL Server interactive application or a SQL Server script.
Note: Before setting up a Linked Server, there are a few things to consider when using
Windows Vista or later versions of Windows. SQL Server runs as a service on your system.
Depending on how the service is set up on Windows Vista or later versions, a service may not
be able to use shared memory connections, it may not be able to start a server, and it may not be
able to access User Data Source definitions. For example, a service logged in as a Network
Service cannot start servers, connect via shared memory, or access User Data Sources. For
these situations, the SAP Sybase IQ server must be started ahead of time and the TCPIP
communication protocol must be used. Also, if a data source is to be used, it must be a System
Data Source.
Prerequisites
SQL Server 2000 or later.
Task
1. For Microsoft SQL Server 2005/2008, start SQL Server Management Studio. For other
versions of SQL Server, the name of this application and the steps to setting up a Linked
Server may vary.
In the Object Explorer pane, expand Server Objects » Linked Servers. Right-click
Linked Servers and then click New Linked Server.
2. Fill in the General page.
The Linked Server field on the General page should contain a Linked Server name (like
SADATABASE in the example above).
The Other Data Source option should be chosen, and SQL Anywhere OLE DB
Provider 16 should be chosen from the Provider list.
The Product Name field can be anything you like (for example, SAP Sybase IQ or your
application name).
The Data Source field can contain an ODBC data source name (DSN). This is a
convenience option and a data source name is not required. If you use a System DSN, it
must be a 32-bit DSN for 32-bit versions of SQL Server or a 64-bit DSN for 64-bit versions
of SQL Server.
Data Source: SAP Sybase IQ 16 Demo
The Provider String field can contain additional connection parameters such as UserID
(UID), ServerName (Server), and DatabaseFile (DBF).
Provider string: Server=myserver;DBF=sample.db
The Location field can contain the equivalent of the SAP Sybase IQ Host connection
parameter (for example, localhost:4444 or 10.25.99.253:2638).
Location: AppServer-pc:2639
The Initial Catalog field can contain the name of the database to connect to (for example,
demo). The database must have been previously started.
Initial Catalog: demo
The combination of these last four fields and the user ID and password from the Security
page must contain enough information to successfully connect to a database server.
3. Instead of specifying the database user ID and password as a connection parameter in the
Provider String field where it would be exposed in plain text, you can fill in the Security
page.
In SQL Server 2005/2008, click the Be made using this security context option and fill in
the Remote login and With password fields (the password is displayed as asterisks).
4. Go to the Server Options page.
Enable the RPC and RPC Out options.
Programming 331
OLE DB and ADO Development
The technique for doing this varies with different versions of Microsoft SQL Server. In
SQL Server 2000, there are two checkboxes that must be checked for these two options. In
SQL Server 2005/2008, the options are True/False settings. Make sure that they are set
True. The Remote Procedure Call (RPC) options must be set to execute stored
procedure/function calls in an SAP Sybase IQ database and pass parameters in and out
successfully.
5. Choose the Allow Inprocess provider option.
The technique for doing this varies with different versions of Microsoft SQL Server. In
SQL Server 2000, there is a Provider Options button that takes you to the page where you
can choose this option. For SQL Server 2005/2008, right-click the SAOLEDB.16 provider
name under Linked Servers » Providers and click Properties. Make sure the Allow
Inprocess checkbox is checked. If the Inprocess option is not chosen, queries fail.
6. Other provider options can be ignored. Several of these options pertain to SQL Server
backwards compatibility and have no effect on the way SQL Server interacts with the SAP
Sybase IQ OLE DB provider. Examples are Nested queries and Supports LIKE
operator. Other options, when selected, may result in syntax errors or degraded
performance.
Prerequisites
SQL Server 2005 or later.
Task
Make the appropriate changes to the following script using the steps below before running it
on SQL Server.
USE [master]
GO
EXEC master.dbo.sp_addlinkedserver @server=N'SADATABASE',
@srvproduct=N'SAP Sybase IQ', @provider=N'SAOLEDB.16',
@datasrc=datasrc=N'Sybase IQ Demo',
@provstr=N'host=localhost:4444;server=myserver;dbn=demo'
GO
EXEC master.dbo.sp_serveroption @server=N'SADATABASE',
@optname=N'rpc', @optvalue=N'true'
GO
EXEC master.dbo.sp_serveroption @server=N'SADATABASE',
@optname=N'rpc out', @optvalue=N'true'
GO
-- Set remote login
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname = N'SADATABASE',
@locallogin = NULL , @useself = N'False',
Your modified script can be run under Microsoft SQL Server to create a new Linked Server.
Programming 333
OLE DB and ADO Development
ICommandText Set the SQL statement text for Only the DBGUID_DEFAULT
ICommand. SQL dialect is supported.
IConvertType Supported.
Programming 335
OLE DB and ADO Development
ITransaction Commit or abort transactions. Not all the flags are supported.
ITransactionJoin Support distributed transac- Not all the flags are supported.
tions.
Programming 337
OLE DB and ADO Development
of the registry, so that ADO can locate the DLL when the SAOLEDB provider is called. If you
change the location of your DLL, you must re-register it.
Example
The following commands register the SAP Sybase IQ OLE DB provider when run from the
directory where the provider is installed:
regsvr32 dboledb16.dll
regsvr32 dboledba16.dll
ODBC CLI
ODBC (Open Database Connectivity) is a standard call level interface (CLI) developed by
Microsoft Corporation. It is based on the SQL Access Group CLI specification. ODBC
applications can run against any data source that provides an ODBC driver. ODBC is a good
choice for a programming interface if you want your application to be portable to other data
sources that have ODBC drivers.
ODBC conformance
SAP Sybase IQ provides support for ODBC 3.5, which is supplied as part of the Microsoft
Data Access Kit 2.7.
Programming 339
ODBC CLI
which defines all the functions, data types, and constant definitions required to write an ODBC
program.
Perform the following tasks to include the ODBC header file in a C/C++ source file:
1. Add an include line referencing the appropriate platform-specific header file to your
source file. The lines to use are as follows:
Operating system Include line
Windows #include "ntodbc.h"
Unix #include "unixodbc.h"
Windows Mobile #include "ntodbc.h"
2. Add the directory containing the header file to the include path for your compiler.
Both the platform-specific header files and odbc.h are installed in the SDK\Include
subdirectory of your SAP Sybase IQ installation directory.
3. When building ODBC applications for Unix, you might have to define the macro "UNIX"
for 32-bit applications or "UNIX64" for 64-bit applications to obtain the correct data
alignment and sizes. This step is not required if you are using one of the following
supported compilers:
Example
The following command illustrates how to add the directory containing the platform-specific
import library to the list of library directories in your LIB environment variable:
set LIB=%LIB%;c:\mssdk\v7.0\lib
The following command illustrates how to compile and link the application stored in odbc.c
using the Microsoft compile and link tool:
cl odbc.c /I"%IQDIR16%\SDK\Lib\X86\Include" odbc32.lib
ODBC driver
The ODBC driver is a shared object or shared library. Separate versions of the SAP Sybase IQ
ODBC driver are supplied for single-threaded and multithreaded applications. A generic SAP
Sybase IQ ODBC driver is supplied that will detect the threading model in use and direct calls
to the appropriate single-threaded or multithreaded library.
The ODBC drivers are the following files:
Operating system Threading model ODBC driver
(all Unix except HP-UX) Generic libdbodbc16.so
(libdbodbc16.so.1)
(all Unix except HP-UX) Single threaded libdbodbc16_n.so
(libdbodbc16_n.so.
1)
(all Unix except HP-UX) Multithreaded libdbodbc16_r.so
(libdbodbc16_r.so.
1)
HP-UX Generic libdbodbc16.sl
(libdbodbc16.sl.1)
HP-UX Single threaded libdbodbc16_n.sl
(libdbodbc16_n.sl.
1)
HP-UX Multithreaded libdbodbc16_r.sl
(libdbodbc16_r.sl.
1)
Programming 341
ODBC CLI
The libraries are installed as symbolic links to the shared library with a version number (shown
in parentheses).
When linking an ODBC application on Unix, link your application against the generic ODBC
driver libdbodbc16. When deploying your application, ensure that the appropriate (or all)
ODBC driver versions (non-threaded or threaded) are available in the user's library path.
Alternatively, you can use the SAP Sybase IQ driver manager on platforms where it is
available.
ODBC driver is provided. This version of the ODBC driver does not support the wide call
interface (for example, SQLConnectW).
The shared object name of the driver is libdbodbcansi16_r. Only a threaded variant of
the driver is provided. Certain frameworks, such as Real Basic, do not work with the dylib and
require the bundle.
The regular ODBC driver treats SQLWCHAR strings as UTF-16 strings. This driver cannot be
used with some ODBC driver managers, such as iODBC, which treat SQLWCHAR strings as
UTF-32 strings. When dealing with Unicode-enabled drivers, these driver managers translate
narrow calls from the application to wide calls into the driver. An ANSI-only driver gets
around this behavior, allowing the driver to be used with such driver managers, as long as the
application does not make any wide calls. Wide calls through iODBC, or any other driver
manager with similar semantics, remain unsupported.
ODBC Samples
Several ODBC samples are included with SAP Sybase IQ. You can find the samples in the
%ALLUSERSPROFILE%\SybaseIQ\samples\SQLAnywhere\C directory
(Windows) and $SYBASE/IQ-16_0/samples/sqlanywhere/c directory (UNIX).
The samples in directories starting with ODBC illustrate separate and simple ODBC tasks,
such as connecting to a database and executing statements. A complete sample ODBC
program is supplied in the odbc.c file. This program performs the same actions as the
embedded SQL dynamic cursor example program that is in the same directory.
Prerequisites
For x64 platform builds, you may need to set up the correct environment for compiling and
linking. Here is an example that builds the sample programs for an x64 platform.
set mssdk=c:\mssdk\v7.0
build64
Task
A batch file located in the %ALLUSERSPROFILE%\SybaseIQ\samples
\SQLAnywhere\C directory can be used to compile and link all the sample applications.
Programming 343
ODBC CLI
Prerequisites
There are no prerequisites for this task.
Task
A shell script located in the $SYBASE/IQ-16_0/samples/sqlanywhere/c
directory can be used to compile and link all the sample applications.
ODBC handles
ODBC applications use a small set of handles to define basic features such as database
connections and SQL statements. A handle is a 32-bit value.
The following handles are used in essentially all ODBC applications:
• Environment – The environment handle provides a global context in which to access data.
Every ODBC application must allocate exactly one environment handle upon starting, and
must free it at the end.
Programming 345
ODBC CLI
For information, see SQLAllocHandle in the Microsoft ODBC API Reference at http://
msdn.microsoft.com/en-us/library/ms712455.aspx.
SQLFreeHandle takes the following parameters:
• an identifier for the type of item being freed
• the handle of the item being freed
For information, see SQLFreeHandle in the Microsoft ODBC API Reference at http://
msdn.microsoft.com/en-us/library/ms710123.aspx.
Example
The following code fragment allocates and frees an environment handle:
SQLRETURN rc;
SQLHENV env;
rc = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env );
if( rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO )
{
.
.
.
}
SQLFreeHandle( SQL_HANDLE_ENV, env );
ODBC example
A simple ODBC program that connects to the SAP Sybase IQ sample database and
immediately disconnects can be found in %IQDIRSAMP16%\SQLAnywhere
\ODBCConnect\odbcconnect.cpp. This example shows the steps required in setting
up the environment to make a connection to a database server, as well as the steps required in
disconnecting from the server and freeing up resources.
SQLDriverConnect can also be used to connect without specifying a data source. The
Sybase IQ ODBC driver name is specified instead. The following example connects to a
server and database that is already running.
SQLSMALLINT cso;
SQLCHAR scso[2048];
For more information, see SQLDriverConnect in the Microsoft ODBC API Reference at
http://msdn.microsoft.com/en-us/library/ms715433.aspx.
• SQLBrowseConnect – Connects to a data source using a connection string, like
SQLDriverConnect.
SQLBrowseConnect allows your application to build its own windows to prompt for
connection information and to browse for data sources used by a particular driver (in this
case the Sybase IQ ODBC driver).
For more information, see SQLBrowseConnect in the Microsoft ODBC API Reference at
http://msdn.microsoft.com/en-us/library/ms714565.aspx.
Prerequisites
There are no prerequisites for this task.
Task
You can find a complete sample in %ALLUSERSPROFILE%\SybaseIQ\samples
\ODBCConnect\odbcconnect.cpp.
Programming 347
ODBC CLI
For example:
rc = SQLAllocHandle( SQL_HANDLE_DBC, env, &dbc );
4. Set any connection attributes that must be set before connecting.
Some connection attributes must be set before establishing a connection or after
establishing a connection, while others can be set either before or after. The
SQL_AUTOCOMMIT attribute is one that can be set before or after:
rc = SQLSetConnectAttr( dbc, SQL_AUTOCOMMIT,
(SQLPOINTER)SQL_AUTOCOMMIT_OFF, 0 );
By default, ODBC operates in autocommit mode. This mode is turned off by setting
SQL_AUTOCOMMIT to false.
5. If necessary, assemble the data source or connection string.
Depending on your application, you may have a hard-coded data source or connection
string, or you may store it externally for greater flexibility.
6. Call the ODBC connection function.
For example:
if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)
{
printf( "dbc allocated\n" );
rc = SQLConnect( dbc,
(SQLCHAR *) "Sybase IQ Demo", SQL_NTS,
(SQLCHAR *) "<user_id>", SQL_NTS,
(SQLCHAR *) "<password>", SQL_NTS );
if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)
{
// Successfully connected.
Every string passed to ODBC has a corresponding length. If the length is unknown, you
can pass SQL_NTS indicating that it is a Null Terminated String whose end is marked by
the null character (\0).
The application, when built and run, establishes an ODBC connection.
SQL_TXN_REPEATABLE_READ
SQL_TXN_SERIALIZABLE
SA_SQL_TXN_SNAPSHOT
SA_SQL_TXN_STATEMENT_SNAPSHOT
SA_SQL_TXN_READONLY_STATEMENT_SNAPSHOT
• time_format – hh:nn:ss
• timestamp_format – yyyy-mm-dd hh:nn:ss.ssssss
• timestamp_with_time_zone_format – yyyy-mm-dd hh:nn:ss.ssssss +hh:nn
To restore the default option setting, execute a SET statement. Here is an example of a
statement that will reset the timestamp_format option.
set temporary option timestamp_format =
Programming 349
ODBC CLI
The returned value will be the same as the parameter value that is passed to the message
handler callback routine.
• SA_REGISTER_VALIDATE_FILE_TRANSFER_CALLBACK – This is used to
register a file transfer validation callback function. Before allowing any transfer to take
place, the ODBC driver will invoke the validation callback, if it exists. If the client data
transfer is being requested during the execution of indirect statements such as from within
a stored procedure, the ODBC driver will not allow a transfer unless the client application
has registered a validation callback. The conditions under which a validation call is made
are described more fully below.
The callback prototype is as follows:
int SQL_CALLBACK file_transfer_callback(
void * sqlca,
char * file_name,
int is_write
);
The file_name parameter is the name of the file to be read or written. The is_write
parameter is 0 if a read is requested (transfer from the client to the server), and non-zero for
a write. The callback function should return 0 if the file transfer is not allowed, non-zero
otherwise.
For data security, the server tracks the origin of statements requesting a file transfer. The
server determines if the statement was received directly from the client application. When
initiating the transfer of data from the client, the server sends the information about the
origin of the statement to the client software. On its part, the ODBC driver allows
unconditional transfer of data only if the data transfer is being requested due to the
execution of a statement sent directly by the client application. Otherwise, the application
must have registered the validation callback described above, in the absence of which the
transfer is denied and the statement fails with an error. If the client statement invokes a
stored procedure already existing in the database, then the execution of the stored
procedure itself is considered not to have been for a client initiated statement. However, if
the client application explicitly creates a temporary stored procedure then the execution of
the stored procedure results in the server treating the procedure as having been client
initiated. Similarly, if the client application executes a batch statement, then the execution
of the batch statement is considered as being done directly by the client application.
• SA_SQL_ATTR_TXN_ISOLATION – This is used to set an extended transaction
isolation level. The following example sets a Snapshot isolation level:
SQLAllocHandle( SQL_HANDLE_DBC, env, &dbc );
SQLSetConnectAttr( dbc, SA_SQL_ATTR_TXN_ISOLATION,
SA_SQL_TXN_SNAPSHOT, SQL_IS_UINTEGER );
Compare this with the actual function prototype found in sql.h in Microsoft Visual Studio
version 8.
SQLRETURN SQL_API SQLGetData(
SQLHSTMT StatementHandle,
SQLUSMALLINT ColumnNumber,
SQLSMALLINT TargetType,
SQLPOINTER TargetValue,
Programming 351
ODBC CLI
SQLLEN BufferLength,
SQLLEN *StrLen_or_Ind);
As you can see, the BufferLength and StrLen_or_Ind parameters are now typed as SQLLEN,
not SQLINTEGER. For the 64-bit platform, these are 64-bit quantities, not 32-bit quantities as
indicated in the Microsoft documentation.
To avoid issues with cross-platform compilation, SAP Sybase IQ provides its own ODBC
header files. For Windows platforms, you should include the ntodbc.h header file. For Unix
platforms such as Linux, you should include the unixodbc.h header file. Use of these
header files ensures compatibility with the corresponding SAP Sybase IQ ODBC driver for
the target platform.
The following table lists some common ODBC types that have the same or different storage
sizes on 64-bit and 32-bit platforms.
If you declare data variables and parameters incorrectly, then you may encounter incorrect
software behavior.
The following table summarizes the ODBC API function prototypes that have changed with
the introduction of 64-bit support. The parameters that are affected are noted. The parameter
name as documented by Microsoft is shown in parentheses when it differs from the actual
parameter name used in the function prototype. The parameter names are those used in the
Microsoft Visual Studio version 8 header files.
Programming 353
ODBC CLI
Some values passed into and returned from ODBC API calls through pointers have changed to
accommodate 64-bit applications. For example, the following values for the SQLSetStmtAttr
and SQLSetDescField functions are no longer SQLINTEGER/SQLUINTEGER. The same
rule applies to the corresponding parameters for the SQLGetStmtAttr and SQLGetDescField
functions.
ODBC API Type for Value/ValuePtr variable
SQLSetStmtAttr(SQL_ATTR_FETCH_BOOK- SQLLEN * value
MARK_PTR)
For more information, see the Microsoft article "ODBC 64-Bit API Changes in MDAC 2.7" at
http://support.microsoft.com/kb/298678.
Programming 355
ODBC CLI
The x86, x64, and PowerPC platforms do not require memory alignment. The x64 platform
includes Advanced Micro Devices (AMD) AMD64 processors and Intel Extended Memory
64 Technology (EM64T) processors.
cannot be seen. The re-execution of the read statement is affected by others. This does not
support a repeatable read. This is the default value for isolation level.
• SQL_TXN_READ_COMMITTED – Set isolation level to 1. When this attribute value
is set, it does not isolate data read from changes by others, and changes made by others can
be seen. The re-execution of the read statement is affected by others. This does not support
a repeatable read.
• SQL_TXN_REPEATABLE_READ – Set isolation level to 2. When this attribute value
is set, it isolates any data read from changes by others, and changes made by others cannot
be seen. The re-execution of the read statement is affected by others. This supports a
repeatable read.
• SQL_TXN_SERIALIZABLE – Set isolation level to 3. When this attribute value is set, it
isolates any data read from changes by others, and changes made by others cannot be seen.
The re-execution of the read statement is not affected by others. This supports a repeatable
read.
• SA_SQL_TXN_SNAPSHOT – Set isolation level to Snapshot. When this attribute value
is set, it provides a single view of the database for the entire transaction.
• SA_SQL_TXN_STATEMENT_SNAPSHOT – Set isolation level to Statement-
snapshot. When this attribute value is set, it provides less consistency than Snapshot
isolation, but may be useful when long running transactions result in too much space being
used in the temporary file by the version store.
• SA_SQL_TXN_READONLY_STATEMENT_SNAPSHOT – Set isolation level to
Readonly-statement-snapshot. When this attribute value is set, it provides less consistency
than Statement-snapshot isolation, but avoids the possibility of update conflicts.
Therefore, it is most appropriate for porting applications originally intended to run under
different isolation levels.
The allow_snapshot_isolation database option must be set to On to use the Snapshot,
Statement-snapshot, or Readonly-statement-snapshot settings.
For more information, see SQLSetConnectAttr in the Microsoft ODBC API Reference at
http://msdn.microsoft.com/en-us/library/ms713605.aspx.
Example
The following fragment sets the isolation level to Snapshot:
SQLAllocHandle( SQL_HANDLE_DBC, env, &dbc );
SQLSetConnectAttr( dbc, SQL_ATTR_TXN_ISOLATION,
SA_SQL_TXN_SNAPSHOT, SQL_IS_UINTEGER );
Programming 357
ODBC CLI
request this behavior. ODBC defines a read-only, forward-only cursor, and SAP Sybase IQ
provides a cursor optimized for performance in this case.
For applications that need to scroll both forward and backward through a result set, such as
many graphical user interface applications, cursor behavior is more complex. What does the
application when it returns to a row that has been updated by some other application? ODBC
defines a variety of scrollable cursors to allow you to build in the behavior that suits your
application. SAP Sybase IQ provides a full set of cursors to match the ODBC scrollable cursor
types.
You set the required ODBC cursor characteristics by calling the SQLSetStmtAttr function that
defines statement attributes. You must call SQLSetStmtAttr before executing a statement that
creates a result set.
You can use SQLSetStmtAttr to set many cursor characteristics. The characteristics that
determine the cursor type that SAP Sybase IQ supplies include the following:
• SQL_ATTR_CURSOR_SCROLLABLE – Set to SQL_SCROLLABLE for a scrollable
cursor and SQL_NONSCROLLABLE for a forward-only cursor.
SQL_NONSCROLLABLE is the default.
• SQL_ATTR_CONCURRENCY – Set to one of the following values:
• SQL_CONCUR_READ_ONLY – Disallow updates.
SQL_CONCUR_READ_ONLY is the default.
• SQL_CONCUR_LOCK – Use the lowest level of locking sufficient to ensure that the
row can be updated.
• SQL_CONCUR_ROWVER – Use optimistic concurrency control, comparing row
versions such as SQLBase ROWID or Sybase TIMESTAMP.
• SQL_CONCUR_VALUES – Use optimistic concurrency control, comparing values.
For more information, see SQLSetStmtAttr in the Microsoft ODBC API Reference at http://
msdn.microsoft.com/en-us/library/ms712631.aspx.
Example
The following fragment requests a read-only, scrollable cursor:
SQLAllocHandle( SQL_HANDLE_STMT, dbc, &stmt );
SQLSetStmtAttr( stmt, SQL_ATTR_CURSOR_SCROLLABLE,
SQL_SCROLLABLE, SQL_IS_UINTEGER );
Data retrieval
To retrieve rows from a database, you execute a SELECT statement using SQLExecute or
SQLExecDirect. This opens a cursor on the statement.
You then use SQLFetch or SQLFetchScroll to fetch rows through the cursor. These functions
fetch the next rowset of data from the result set and return data for all bound columns. Using
SQLFetchScroll, rowsets can be specified at an absolute or relative position or by bookmark.
SQLFetchScroll replaces the older SQLExtendedFetch from the ODBC 2.0 specification.
When an application frees the statement using SQLFreeHandle, it closes the cursor.
To fetch values from a cursor, your application can use either SQLBindCol or SQLGetData. If
you use SQLBindCol, values are automatically retrieved on each fetch. If you use
SQLGetData, you must call it for each column after each fetch.
SQLGetData is used to fetch values in pieces for columns such as LONG VARCHAR or
LONG BINARY. As an alternative, you can set the SQL_ATTR_MAX_LENGTH statement
attribute to a value large enough to hold the entire value for the column. The default value for
SQL_ATTR_MAX_LENGTH is 256 KB.
The SAP Sybase IQ ODBC driver implements SQL_ATTR_MAX_LENGTH in a different
way than intended by the ODBC specification. The intended meaning for
SQL_ATTR_MAX_LENGTH is that it be used as a mechanism to truncate large fetches. This
might be done for a "preview" mode where only the first part of the data is displayed. For
example, instead of transmitting a 4 MB blob from the server to the client application, only the
first 500 bytes of it might be transmitted (by setting SQL_ATTR_MAX_LENGTH to 500).
The SAP Sybase IQ ODBC driver does not support this implementation.
The following code fragment opens a cursor on a query and retrieves data through the cursor.
Error checking has been omitted to make the example easier to read. The fragment is taken
from a complete sample, which can be found in %IQDIRSAMP16%\SQLAnywhere
\ODBCSelect\odbcselect.cpp.
SQLINTEGER cbDeptID = 0, cbDeptName = SQL_NTS, cbManagerID = 0;
SQLCHAR deptName[ DEPT_NAME_LEN + 1 ];
SQLSMALLINT deptID, managerID;
SQLHENV env;
SQLHDBC dbc;
SQLHSTMT stmt;
SQLRETURN rc;
Programming 359
ODBC CLI
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 a 32-bit 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
ODBC provides bookmarks, which are values used to identify rows in a cursor. SAP Sybase
IQ supports bookmarks for value-sensitive and insensitive cursors. For example, the ODBC
cursor types SQL_CURSOR_STATIC and SQL_CURSOR_KEYSET_DRIVEN support
bookmarks while cursor types SQL_CURSOR_DYNAMIC and
SQL_CURSOR_FORWARD_ONLY do not.
Before ODBC 3.0, a database could specify only whether it supported bookmarks or not: there
was no interface to provide this information for each cursor type. There was no way for a
database server to indicate for what kind of cursor bookmarks were supported. For ODBC 2
applications, SAP Sybase IQ 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.
Programming 361
ODBC CLI
Example 2
This example calls a procedure that returns a result set. In the example, the variable
num_columns 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.
SQLRETURN rc;
SQLHDBC dbc;
SQLHSTMT stmt;
SQLSMALLINT num_columns;
SQLCHAR ID[ 10 ];
SQLCHAR Surname[ 20 ];
SQLExecDirect( stmt,
"CREATE PROCEDURE EmployeeList() "
"RESULT( ID CHAR(10), Surname CHAR(20) ) "
"BEGIN "
" SELECT EmployeeID, Surname FROM Employees "
"END", SQL_NTS );
for( ;; )
{
rc = SQLFetch( stmt );
if( rc == SQL_NO_DATA_FOUND )
{
rc = SQLMoreResults( stmt );
if( rc == SQL_NO_DATA_FOUND ) break;
}
else
{
do_something( ID, Surname );
}
}
• {t time-string} – The time string is any time value accepted by SAP Sybase IQ.
• {ts date-string time-string} – The date/time string is any timestamp value accepted by
SAP Sybase IQ.
• {guid uuid-string} – The uuid-string is any valid GUID string, for example, 41dfe9ef-
db91-11d2-8c43-006008d26a6f.
• {oj outer-join-expr} – The outer-join-expr is a valid OUTER JOIN expression accepted
by SAP Sybase IQ.
• {? = call func(p1,...)} – The function is any valid function call accepted by SAP Sybase
IQ.
• {call proc(p1,...)} – The procedure is any valid stored procedure call accepted by SAP
Sybase IQ.
• {fn func(p1,...)} – The function is any one of the library of functions listed below.
You can use the escape syntax to access a library of functions implemented by the ODBC
driver that includes number, string, time, date, and system functions.
For example, to obtain the current date in a database management system-neutral way, you
would execute the following:
SELECT { FN CURDATE() }
The following tables list the functions that are supported by the SAP Sybase IQ ODBC driver.
Programming 363
ODBC CLI
PI POSITION NOW
SQRT SUBSTRING
TAN UCASE
TRUNCATE
Returns the integer number of intervals of type interval by which timestamp-expr2 is greater
than timestamp-expr1. Valid values of interval are shown below.
interval DATEADD/DATE-
DIFF date-part
mapping
SQL_TSI_YEAR YEAR
SQL_TSI_QUARTER QUARTER
interval DATEADD/DATE-
DIFF date-part
mapping
SQL_TSI_MONTH MONTH
SQL_TSI_WEEK WEEK
SQL_TSI_DAY DAY
SQL_TSI_HOUR HOUR
SQL_TSI_MINUTE MINUTE
SQL_TSI_SECOND SECOND
SQL_TSI_FRAC_SE MICROSECOND -
COND The DATEADD and
DATEDIFF functions
do not support a reso-
lution of nanoseconds.
Interactive SQL
The ODBC escape syntax is identical to the JDBC escape syntax. In Interactive SQL, which
uses JDBC, the braces must be doubled. There must not be a space between successive braces:
"{{" is acceptable, but "{ {" is not. As well, you cannot use newline characters in the statement.
The escape syntax cannot be used in stored procedures because they are not parsed by
Interactive SQL.
For example, to obtain the number of weeks in February 2013, execute the following in
Interactive SQL:
SELECT {{ fn TIMESTAMPDIFF(SQL_TSI_WEEK, '2013-02-01T00:00:00',
'2013-03-01T00:00:00' ) }}
Programming 365
ODBC CLI
Every environment, connection, and statement handle can have one or more errors or
warnings associated with it. Each call to SQLError or SQLGetDiagRec returns the
information for one error and removes the information for that error. If you do not call
SQLError or SQLGetDiagRec to remove all errors, the errors are removed on the next
function call that passes the same handle as a parameter.
Each call to SQLError passes three handles for an environment, connection, and statement.
The first call uses SQL_NULL_HSTMT to get the error associated with a connection.
Similarly, a call with both SQL_NULL_DBC and SQL_NULL_HSTMT get any error
associated with the environment handle.
Each call to SQLGetDiagRec can pass either an environment, connection or statement handle.
The first call passes in a handle of type SQL_HANDLE_DBC to get the error associated with a
connection. The second call passes in a handle of type SQL_HANDLE_STMT to get the error
associated with the statement that was just executed.
SQLError and SQLGetDiagRec return SQL_SUCCESS if there is an error to report (not
SQL_ERROR), and SQL_NO_DATA_FOUND if there are no more errors to report.
Example 1
The following code fragment uses SQLError and return codes:
SQLRETURN rc;
SQLHDBC dbc;
SQLHSTMT stmt;
UCHAR errmsg[100];
Example 2
The following code fragment uses SQLGetDiagRec and return codes:
SQLRETURN rc;
SQLHDBC dbc;
SQLHSTMT stmt;
SQLSMALLINT errmsglen;
SQLINTEGER errnative;
SQLCHAR errmsg[255];
SQLCHAR errstate[5];
rc = SQLExecDirect( stmt,
"DELETE FROM SalesOrderItems WHERE ID=2015",
SQL_NTS );
if( rc == SQL_ERROR )
{
SQLGetDiagRec( SQL_HANDLE_STMT, stmt, 1, errstate,
&errnative, errmsg, sizeof(errmsg), &errmsglen );
print_error( "Failed to delete items", errstate, errnative,
errmsg );
Programming 367
ODBC CLI
return;
}
Programming 369
Java in the Database
computational logic. For example, you could design, write, and compile Java code to create an
Employees class complete with various methods that perform operations on an Employees
table. You install your Java classes as objects into a database and write SQL cover functions or
procedures to invoke the methods in the Java classes.
Once installed, you can execute these classes from the database server using stored
procedures. For example, the following statement creates the interface to a Java procedure:
CREATE PROCEDURE MyMethod()
EXTERNAL NAME 'JDBCExample.MyMethod()V'
LANGUAGE JAVA;
SAP Sybase IQ facilitates a runtime environment for Java classes, not a Java development
environment. You need a Java development environment, such as the Java Development Kit
(JDK), to write and compile Java. You also need a Java Runtime Environment to execute Java
classes.
You can use many of the classes that are part of the Java API as included in the Java
Development Kit. You can also use classes created and compiled by Java developers.
Programming 371
Java in the Database
java Invoice
}
}
You can expose the result set using a CREATE PROCEDURE statement that indicates the
number of result sets returned from the procedure and the signature of the Java method.
A CREATE PROCEDURE statement indicating a result set could be defined as follows:
CREATE PROCEDURE result_set()
RESULT (SurName person_name_t)
DYNAMIC RESULT SETS 1
EXTERNAL NAME
'MyResultSet.return_rset([Ljava/sql/ResultSet;)V'
LANGUAGE JAVA;
You can open a cursor on this procedure, just as you can with any SAP Sybase IQ procedure
returning result sets.
The string ([Ljava/sql/ResultSet;)V is a Java method signature that is a compact
character representation of the number and type of the parameters and return value.
The string ([I)Z is a Java method signature, indicating that the method has a single
parameter, which is an array of integers, and returns a Boolean value. Define the method so
that the method parameter you want to use as an OUT or INOUT parameter is an array of a
Java data type that corresponds to the SQL data type of the OUT or INOUT parameter.
To test this, call the stored procedure with an uninitialized variable.
Programming 373
Java in the Database
You can unload the Java VM when Java is not in use using the STOP JAVA statement. The
syntax is:
STOP JAVA;
((ianywhere.sa.jvm.SAClassLoader)classLoader).addShutdownHook( hook
);
The SDHookThread class extends the standard Thread class and that the above code must be
executed by a class that was loaded by the ClassLoader for the current connection. Any class
that is installed within the database and that is later called via an external environment call is
automatically executed by the correct SQL Anywhere Java VM ClassLoader.
To remove a shutdown hook from the SQL Anywhere Java VM ClassLoader list, an
application will need to execute code similar to the following:
ClassLoader classLoader =
Thread.currentThread().getContextClassLoader();
((ianywhere.sa.jvm.SAClassLoader)classLoader).removeShutdownHook( h
ook );
The above code must be executed by a class that was loaded by the ClassLoader for the current
connection.
Programming 375
Java in the Database
JDBC CLI
JDBC is a call-level interface for Java applications. JDBC provides you with a uniform
interface to a wide range of relational databases, and provides a common base on which higher
level tools and interfaces can be built. JDBC is now a standard part of Java and is included in
the JDK.
SAP Sybase IQ includes a 4.0 driver, which is a Type 2 driver.
SAP Sybase IQ also supports a pure Java JDBC driver, named jConnect, which is available
from SAP.
In addition to using JDBC as a client-side application programming interface, you can also use
JDBC inside the database server to access data by using Java in the database.
JDBC Applications
You can develop Java applications that use the JDBC API to connect to SAP Sybase IQ.
Several of the applications supplied with SAP Sybase IQ use JDBC, such as Interactive SQL.
Java and JDBC are also important programming languages for developing UltraLite®
applications.
JDBC can be used both from client applications and inside the database. Java classes using
JDBC provide a more powerful alternative to SQL stored procedures for incorporating
programming logic into the database.
Programming 377
JDBC CLI
JDBC provides a SQL interface for Java applications: to access relational data from Java, you
do so using JDBC calls.
The phrase client application applies both to applications running on a user's computer and to
logic running on a middle-tier application server.
The examples illustrate the distinctive features of using JDBC in SAP Sybase IQ. For more
information about JDBC programming, see any JDBC programming book.
You can use JDBC with SAP Sybase IQ in the following ways:
• JDBC on the client – Java client applications can make JDBC calls to SAP Sybase IQ.
The connection takes place through a JDBC driver.
SAP Sybase IQ includes a JDBC 4.0 driver, which is a Type 2 JDBC driver, and also
supports the jConnect driver for pure Java applications, which is a Type 4 JDBC driver.
• JDBC in the database – Java classes installed into a database can make JDBC calls to
access and modify data in the database using an internal JDBC driver.
JDBC resources
• Example source code – You can find source code for the examples in this section in the
directory %ALLUSERSPROFILE%\SybaseIQ\samples\SQLAnywhere\JDBC.
• JDBC Specification – You can find more information about the JDBC Data Access API at
http://www.oracle.com/technetwork/java/javase/tech/index-jsp-136101.html.
• Required software – You need TCP/IP to use the jConnect driver.
The jConnect driver is available at http://www.sybase.com/products/allproductsa-z/
softwaredeveloperkit/jconnect.
JDBC Drivers
SAP Sybase IQ supports the following JDBC drivers:
• SQL Anywhere 16 JDBC 4.0 driver – This driver communicates with SAP Sybase IQ
using the Command Sequence client/server protocol. Its behavior is consistent with
ODBC, embedded SQL, and OLE DB applications. The SQL Anywhere 16 JDBC 4.0
driver is the recommended JDBC driver for connecting to SAP Sybase IQ databases. The
JDBC 4.0 driver can be used only with JRE 1.6 or later.
The JDBC 4.0 driver takes advantage of the new automatic JDBC driver registration.
Hence, if an application wants to make use of the JDBC 4.0 driver, it no longer needs to
perform a Class.forName call to get the JDBC driver loaded. It is instead sufficient to have
the sajdbc4.jar file in the class file path and simply call
DriverManager.getConnection() with a URL that begins with jdbc:sqlanywhere.
The JDBC 4.0 driver contains manifest information to allow it to be loaded as an OSGi
(Open Services Gateway initiative) bundle.
With the JDBC 4.0 driver, metadata for NCHAR data now returns the column type as
java.sql.Types.NCHAR, NVARCHAR, or LONGNVARCHAR. In addition, applications
can now fetch NCHAR data using the Get/SetNString or Get/SetNClob methods instead
of the Get/SetString and Get/SetClob methods.
• jConnect – This driver is a 100% pure Java driver. It communicates with SAP Sybase IQ
using the TDS client/server protocol.
jConnect and jConnect documentation are available at http://www.sybase.com/products/
allproductsa-z/softwaredeveloperkit/jconnect.
When choosing which driver to use, you should consider the following factors:
• Features – The SQL Anywhere 16 JDBC 4.0 driver and jConnect are JDBC 4.0 compliant.
The SQL Anywhere 16 JDBC driver provides fully-scrollable cursors when connected to
an SAP Sybase IQ database. The jConnect JDBC driver provides scrollable cursors when
connected to an SAP Sybase IQ database server, but the result set is cached on the client
side. The jConnect JDBC driver provides fully-scrollable cursors when connected to a
SAP Adaptive Server® Enterprise database.
The JDBC 4.0 API documentation is available at http://www.oracle.com/technetwork/
java/javase/tech/index-jsp-136101.html.
• Pure Java – The jConnect driver is a pure Java solution. The SQL Anywhere 16 JDBC
drivers are based on the SQL Anywhere 16 ODBC driver and are not pure Java solutions.
• Performance – The SQL Anywhere 16 JDBC drivers provide better performance for most
purposes than the jConnect driver.
• Compatibility – The TDS protocol used by the jConnect driver is shared with Adaptive
Server. Some aspects of the driver's behavior are governed by this protocol, and are
configured to be compatible with Adaptive Server.
For information about platform availability for the SQL Anywhere 16 JDBC drivers and
jConnect, see http://www.sybase.com/detail?id=1061806.
Programming 379
JDBC CLI
The ResultSet object contains the data returned from the SQL statement, but exposes it one
row at a time (similar to the way a cursor works).
• Loop over the rows of the result set – The next method of the ResultSet object performs
two actions:
• The current row (the row in the result set exposed through the ResultSet object)
advances one row.
• A boolean value returns to indicate whether there is a row to advance to.
• For each row, retrieve the values – Values are retrieved for each column in the ResultSet
object by identifying either the name or position of the column. You can use the getData
method to get the value from a column on the current row.
Java objects can use JDBC objects to interact with a database and get data for their own use.
The JDBC 4.0 driver takes advantage of the new automatic JDBC driver registration. The
driver is automatically loaded at execution startup when it is in the class file path.
Required Files
The Java component of the SQL Anywhere JDBC 4.0 driver is included in the
sajdbc4.jar file installed into the Java subdirectory of your SAP Sybase IQ installation.
For Windows, the native component is dbjdbc16.dll in the bin32 or bin64
subdirectory of your SAP Sybase IQ installation; for Unix, the native component is
libdbjdbc16.so. This component must be in the system path.
"jdbc:sqlanywhere:UserID=<user_id>;Password=<password>;Start=..." )
;
The Driver connection parameter is not required since neither the ODBC driver nor ODBC
driver manager is used. If present, it will be ignored.
Programming 381
JDBC CLI
Encrypting Passwords
SAP Sybase IQ supports password encryption for jConnect connections.
Prerequisites
You must have the ALTER DATABASE system privilege, and must be the only connection to
the database.
Back up your database files before upgrading. If you attempt to upgrade a database and it fails,
then the database becomes unusable.
Task
jConnect system objects are installed into an SAP Sybase IQ database by default when you use
the iqinit utility. You can add the jConnect system objects to the database when creating the
database or at a later time by upgrading the database.
The jConnect driver takes advantage of the new automatic JDBC driver registration. The
driver is automatically loaded at execution startup when it is in the class file path.
Programming 383
JDBC CLI
As shown in the example, a comma must precede the DatabaseFile connection parameter.
Using the DatabaseFile parameter, you can start a database on a server using jConnect. By
default, the database is started with AutoStop=YES. If you specify utility_db with a
DatabaseFile (DBF) or DatabaseName (DBN) connection parameter (for example,
DBN=utility_db), then the utility database is started automatically.
The following complete Java application is a command line program that connects to a
running database, prints a set of information to your command line, and terminates.
Establishing a connection is the first step any JDBC application must take when working with
database data.
This example illustrates an external connection, which is a regular client/server connection.
Programming 385
JDBC CLI
System.exit(0);
}
}
Importing Packages
The application requires a couple of packages, which are imported in the first lines of
JDBCConnect.java:
• The java.io package contains the Java input/output classes, which are required for printing
to the command prompt window.
• The java.sql package contains the JDBC classes, which are required for all JDBC
applications.
1. Determines which driver to load based on the command line argument. The SQL
Anywhere JDBC 4.0 and jConnect 7.0 drivers are automatically loaded at startup if they
are in the class file path.
2. Connects to the default running database using the selected JDBC driver URL. The
getConnection method establishes a connection using the specified URL.
3. Creates a statement object, which is the container for the SQL statement.
4. Creates a result set object by executing a SQL query.
5. Iterates through the result set, printing the column information.
6. Closes each of the result set, statement, and connection objects.
Prerequisites
A Java Development Kit (JDK) must be installed.
Task
Two different types of connections using JDBC can be made. One is the client-side connection
and the other is the server-side connection. The following example uses a client-side
connection.
If you are using the jConnect driver instead, then use the following (where path is your
jConnect installation directory):
set classpath=.;jconnect-path\classes\jconn4.jar
4. Run the following command to compile the example:
javac JDBCConnect.java
5. Run the following command to execute the example:
java JDBCConnect
Add a command line argument such as jconnect to load a different JDBC driver.
java JDBCConnect jconnect
6. Confirm that a list of identification numbers with customer's names appears at the
command prompt.
Programming 387
JDBC CLI
If the attempt to connect fails, an error message appears instead. Confirm that you have
executed all the steps as required. Check that your class file path is correct. An incorrect
setting may result in a failure to locate a class.
A list of identification numbers with customer's names is displayed.
}
rs.close();
stmt.close();
con.close();
}
catch (SQLException sqe)
{
System.out.println("Unexpected exception : " +
sqe.toString() + ", sqlstate = " +
sqe.getSQLState());
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Prerequisites
A Java Development Kit (JDK) must be installed.
Task
Two different types of connections using JDBC can be made. One is the client-side connection
and the other is the server-side connection. The following example uses a server-side
connection.
Programming 389
JDBC CLI
set classpath=.;%ALLUSERSPROFILE%\SybaseIQ\samples\SQLAnywhere
\JDBC
3. Start a database server with the iqdemo database on your local computer.
4. Enter the following command to compile the example:
javac JDBCConnect2.java
5. Install the class into the sample database using Interactive SQL. Execute the following
statement (a path to the class file may be required):
INSTALL JAVA NEW
FROM FILE 'JDBCConnect2.class';
6. Define a stored procedure named JDBCConnect that acts as a wrapper for the
JDBCConnect2.main method in the class:
CREATE PROCEDURE JDBCConnect(OUT args LONG VARCHAR)
EXTERNAL NAME 'JDBCConnect2.main([Ljava/lang/String;)V'
LANGUAGE JAVA;
7. Call the JDBCConnect2.main method as follows:
CALL JDBCConnect();
The first time a Java class is called in a session, the Java VM must be loaded. This might
take a few seconds.
8. Confirm that a list of identification numbers with customers' names appears in the database
server messages window.
If the attempt to connect fails, an error message appears instead. Confirm that you have
executed all the steps as required.
A list of identification numbers with customer's names is displayed in the database server
messages window.
In this statement, con is the current connection object. You could also set autocommit to
true.
• Setting transaction isolation level – To set the transaction isolation level, the application
must call the Connection.setTransactionIsolation method with one of the following
values.
sybase.jdbc4.sqlanywhere.IConnection.SA_TRANSACTION_SNAPSHOT
);
}
catch( Exception e )
{
System.err.println( "Error! Could not set isolation level" );
System.err.println( e.getMessage() );
printExceptions( (SQLException)e );
}
Programming 391
JDBC CLI
}
finally
{
con.setAutoCommit( oldAutoCommit );
}
This discussion applies not only to autocommit, but also to other connection properties
such as transaction isolation level and read-only mode.
For more information about the getTransactionIsolation, setTransactionIsolation, and
isReadOnly methods, see documentation on the java.sql.Connection interface at http://
docs.oracle.com/javase/6/docs/technotes/guides/jdbc/.
Prerequisites
You must have the MANAGE ANY EXTERNAL OBJECT system privilege.
A Java Development Kit (JDK) must be installed.
Task
If the database server was not started from the same directory as the class file and the path
to the class file is not listed in the database server's CLASSPATH, then you will have to
include the path to the class file in the INSTALL statement.
The JDBCExample class file is installed in the database and ready for demonstration.
Programming 393
JDBC CLI
try
{
int iRows = stmt.executeUpdate(
"INSERT INTO Departments (DepartmentID, DepartmentName)"
+ " VALUES (201, 'Eastern Sales')" );
// Print the number of rows inserted
System.out.println(iRows + " rows inserted");
}
catch (SQLException sqe)
{
System.out.println("Unexpected exception : " +
sqe.toString() + ", sqlstate = " +
sqe.getSQLState());
}
catch (Exception e)
{
e.printStackTrace();
}
}
Notes
• This code fragment is part of the JDBCExample.java file included in the
%ALLUSERSPROFILE%\SybaseIQ\samples\SQLAnywhere\JDBC directory.
• The executeUpdate method returns an integer that reflects the number of rows affected by
the operation. In this case, a successful INSERT would return a value of one (1).
• When run as a server-side class, the output from System.out.println goes to the
database server messages window.
Prerequisites
To create an external procedure, you must have the CREATE PROCEDURE and CREATE
EXTERNAL REFERENCE system privileges. You must also have SELECT, DELETE, and
INSERT privileges on the database object you are modifying.
A Java Development Kit (JDK) must be installed.
Task
The example program displays the updated contents of the Departments table in the
database server messages window.
6. There is a similar method in the example class called DeleteStatic that shows how to delete
the row that has just been added. Call the JDBCExample.main method as follows:
CALL JDBCExample( 'delete' );
The example program displays the updated contents of the Departments table in the
database server messages window.
Rows are inserted and deleted from a table using static SQL statements in a server-side JDBC
application.
Programming 395
JDBC CLI
try
{
// Build the INSERT statement
// ? is a placeholder character
String sqlStr = "INSERT INTO Departments " +
"( DepartmentID, DepartmentName ) " +
"VALUES ( ? , ? )";
Notes
• This code fragment is part of the JDBCExample.java file included in the
%ALLUSERSPROFILE%\SybaseIQ\samples\SQLAnywhere\JDBC directory.
• The executeUpdate method returns an integer that reflects the number of rows affected by
the operation. In this case, a successful INSERT would return a value of one (1).
• When run as a server-side class, the output from System.out.println goes to the
database server messages window.
Prerequisites
To create an external procedure, you must have the CREATE PROCEDURE and CREATE
EXTERNAL REFERENCE system privileges. You must also have SELECT, DELETE, and
INSERT privileges on the database object you are modifying.
A Java Development Kit (JDK) must be installed.
Task
The example program displays the updated contents of the Departments table in the
database server messages window.
6. There is a similar method in the example class called DeleteDynamic that shows how to
delete the row that has just been added.
Define a stored procedure named JDBCDelete that acts as a wrapper for the
JDBCExample.Delete method in the class:
CREATE PROCEDURE JDBCDelete(IN arg1 INTEGER)
EXTERNAL NAME 'JDBCExample.Delete(I)V'
LANGUAGE JAVA;
7. Call the JDBCExample.Delete method as follows:
CALL JDBCDelete( 202 );
Programming 397
JDBC CLI
The example program displays the updated contents of the Departments table in the
database server messages window.
Rows are inserted and deleted from a table using prepared SQL statements in a server-side
JDBC application.
Example:
for( i=0; i < 5; i++ )
{
stmt.setInt( 1, idValue );
stmt.setString( 2, name );
stmt.addBatch();
}
3. The batch must be executed using the executeBatch method of the PreparedStatement
class.
BLOB parameters are not supported in batches.
When using the SQL Anywhere JDBC driver to perform batched inserts, it is recommended
that you use a small column size. Using batched inserts to insert large binary or character data
into long binary or long varchar columns is not recommended and may degrade performance.
The performance can decrease because the SQL Anywhere JDBC driver must allocate large
amounts of memory to hold each of the batched insert rows. In all other cases, using batched
inserts should provide better performance than using individual inserts.
Notes
• This server-side JDBC example is part of the JDBCExample.java file included in the
%ALLUSERSPROFILE%\SybaseIQ\samples\SQLAnywhere\JDBC directory.
• It obtains a connection to the default running database by using getConnection.
• The executeQuery methods return result sets.
Prerequisites
A Java Development Kit (JDK) must be installed.
Programming 399
JDBC CLI
Task
Three different result sets are returned from a server-side JDBC application.
JDBC Notes
Learn about privileges for accessing and executing Java classes.
• Access privileges – Like all Java classes in the database, classes containing JDBC
statements can be accessed by any user if the GRANT EXECUTE statement has granted
them privilege to execute the stored procedure that is acting as a wrapper for the Java
method.
• Execution privileges – Java classes are executed with the privileges of the connection
executing them. This behavior is different from that of stored procedures, which execute
with the privileges of the owner.
JDBC Callbacks
The SQL Anywhere JDBC driver supports two asynchronous callbacks, one for handling the
SQL MESSAGE statement and the other for validating requests for file transfers.
Messages can be sent to the client application from the database server using the SQL
MESSAGE statement. Messages can also be generated by long running database server
statements.
A message handler routine can be created to intercept these messages. The following is an
example of a message handler callback routine.
class T_message_handler implements
sybase.jdbc4.sqlanywhere.ASAMessageHandler
{
private final int MSG_INFO = 0x80 | 0;
private final int MSG_WARNING = 0x80 | 1;
private final int MSG_ACTION = 0x80 | 2;
private final int MSG_STATUS = 0x80 | 3;
T_message_handler()
{
}
switch( sqe.getErrorCode() ) {
case MSG_INFO: msg_type = "INFO "; break;
case MSG_WARNING: msg_type = "WARNING"; break;
case MSG_ACTION: msg_type = "ACTION "; break;
case MSG_STATUS: msg_type = "STATUS "; break;
}
A client file transfer request can be validated. Before allowing any transfer to take place, the
JDBC driver will invoke the validation callback, if it exists. If the client data transfer is being
requested during the execution of indirect statements such as from within a stored procedure,
the JDBC driver will not allow a transfer unless the client application has registered a
validation callback. The conditions under which a validation call is made are described more
fully below. The following is an example of a file transfer validation callback routine.
class T_filetrans_callback implements
sybase.jdbc4.sqlanywhere.SAValidateFileTransferCallback
{
T_filetrans_callback()
{
}
Programming 401
JDBC CLI
The filename argument is the name of the file to be read or written. The is_write parameter is 0
if a read is requested (transfer from the client to the server), and non-zero for a write. The
callback function should return 0 if the file transfer is not allowed, non-zero otherwise.
For data security, the server tracks the origin of statements requesting a file transfer. The server
determines if the statement was received directly from the client application. When initiating
the transfer of data from the client, the server sends the information about the origin of the
statement to the client software. On its part, the JDBC driver allows unconditional transfer of
data only if the data transfer is being requested due to the execution of a statement sent directly
by the client application. Otherwise, the application must have registered the validation
callback described above, in the absence of which the transfer is denied and the statement fails
with an error. If the client statement invokes a stored procedure already existing in the
database, then the execution of the stored procedure itself is considered not to have been for a
client initiated statement. However, if the client application explicitly creates a temporary
stored procedure then the execution of the stored procedure results in the server treating the
procedure as having been client initiated. Similarly, if the client application executes a batch
statement, then the execution of the batch statement is considered as being done directly by the
client application.
The following sample Java application demonstrates the use of the callbacks supported by the
SQL Anywhere JDBC 4.0 driver. You need to place the file %ALLUSERSPROFILE%
\SybaseIQ\samples\java\sajdbc4.jar in your classpath.
import java.io.*;
import java.sql.*;
import java.util.*;
try
{
// create and register message handler callback
T_message_handler message_worker = new
T_message_handler();
((sybase.jdbc4.sqlanywhere.IConnection)con).setASAMessageHandler( m
essage_worker );
((sybase.jdbc4.sqlanywhere.IConnection)con).setSAValidateFileTransf
erCallback( filetran_worker );
stmt = con.createStatement();
System.out.println( "\n==================\n" );
Programming 403
JDBC CLI
{
// Note: Since the file transfer callback returns 1,
// do not expect a SQL exception to be thrown
System.out.println( "SQLException: " +
filetrans_exception.getMessage() );
}
stmt.close();
con.close();
System.out.println( "Disconnected" );
}
catch( SQLException sqe )
{
printExceptions(sqe);
}
}
The functions that are available depend on the JDBC driver that you are using. The following
tables list the functions that are supported by the SQL Anywhere JDBC driver and by the
jConnect driver.
Programming 405
JDBC CLI
PI POSITION NOW
SIGN SOUNDEX
SIN SPACE
SQRT SUBSTRING
TAN UCASE
TRUNCATE
LOG10 TIMESTAMPADD
PI TIMESTAMPDIFF
POWER YEAR
RADIANS
RAND
ROUND
SIGN
SIN
SQRT
TAN
A statement using the escape syntax should work in SAP Sybase IQ, Adaptive Server
Enterprise, Oracle, SQL Server, or another database management system to which you are
connected.
In Interactive SQL, the braces must be doubled. There must not be a space between successive
braces: "{{" is acceptable, but "{ {" is not. As well, you cannot use newline characters in the
statement. The escape syntax cannot be used in stored procedures because they are not parsed
by Interactive SQL.
Programming 407
JDBC CLI
For example, to obtain database properties with the sa_db_info procedure using SQL escape
syntax, you would execute the following in Interactive SQL:
{{CALL sa_db_info( 0 ) }}
Embedded SQL
SQL statements embedded in a C or C++ source file are referred to as embedded SQL. A
preprocessor translates these statements into calls to a runtime library. Embedded SQL is an
ISO/ANSI and IBM standard.
Embedded SQL is portable to other databases and other environments, and is functionally
equivalent in all operating environments. It is a comprehensive, low-level interface that
provides all the functionality available in the product. Embedded SQL requires knowledge of
C or C++ programming languages.
Embedded SQL is a database programming interface for the C and C++ programming
languages. It consists of SQL statements intermixed with (embedded in) C or C++ source
code. These SQL statements are translated by a SQL preprocessor into C or C++ source code,
which you then compile.
Programming 409
Embedded SQL
At runtime, embedded SQL applications use an SAP Sybase IQ interface library called
DBLIB to communicate with a database server. DBLIB is a dynamic link library (DLL) or
shared object on most platforms.
• On Windows operating systems, the interface library is dblib16.dll.
• On Unix operating systems, the interface library is libdblib16.so,
libdblib16.sl, or libdblib16.a, depending on the operating system.
• On Mac OS X, the interface library is libdblib16.dylib.1.
SAP Sybase IQ provides two flavors of embedded SQL. Static embedded SQL is simpler to
use, but is less flexible than dynamic embedded SQL.
Once the program has been successfully preprocessed and compiled, it is linked with the
import library for DBLIB to form an executable file. When the database server is running, this
executable file uses DBLIB to interact with the database server. The database server does not
have to be running when the program is preprocessed.
For Windows, there are 32-bit and 64-bit import libraries for Microsoft Visual C++. The use of
import libraries is one method for developing applications that call functions in DLLs.
However, it is recommended that the library be dynamically loaded, avoiding the use of import
libraries.
Programming 411
Embedded SQL
Option Description
-e level Flag as an error any static embedded SQL that is
not part of a specified standard. The level value
indicates the standard to use. For example,
iqsqlpp -e c03 ... flags any syntax
that is not part of the core SQL/2008 standard.
The supported level values are:
Option Description
-m mode Specify the cursor updatability mode if it is not
specified explicitly in the embedded SQL appli-
cation. The mode can be one of:
Programming 413
Embedded SQL
Option Description
-s len Set the maximum size string that the preprocessor
puts into the C file. Strings longer than this value
are initialized using a list of characters ('a','b','c',
and so on). Most C compilers have a limit on the
size of string literal they can handle. This option is
used to set that upper limit. The default value is
500.
Option Description
-x Change multibyte strings to escape sequences so
that they can pass through compilers.
Supported Compilers
The C language SQL preprocessor has been used with the following compilers:
Programming 415
Embedded SQL
Import Libraries
On Windows platforms, all import libraries are installed in the SDK\Lib subdirectories,
under the SAP Sybase IQ installation directory. Windows import libraries are stored in the
SDK\Lib\x86 and SDK\Lib\x64 subdirectories. An export definition list is stored in
SDK\Lib\Def\dblib.def.
On Unix platforms, all import libraries are installed in the lib32 and lib64 subdirectories,
under the SAP Sybase IQ installation directory.
Operating system Compiler Import library
Windows Microsoft Visual C++ dblibtm.lib
The libdbtasks16 libraries are called by the libdblib16 libraries. Some compilers
locate libdbtasks16 automatically. For others, you need to specify it explicitly.
This example connects to the database, updates the last name of employee number 195,
commits the change, and exits. There is virtually no interaction between the embedded SQL
code and the 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.
Programming 417
Embedded SQL
One of the first embedded SQL statements executed by the C program must be a CONNECT
statement. The CONNECT statement is used to establish a connection with the database
server and to specify the user ID that is used for authorizing all statements executed during the
connection.
Some embedded SQL statements do not generate any C code, or do not involve
communication with the database. These statements are allowed before the CONNECT
statement. Most notable are the INCLUDE statement and the WHENEVER statement for
specifying error processing.
Every C program using embedded SQL must finalize any SQLCA that has been initialized.
db_fini( &sqlca );
Prerequisites
There are no prerequisites for this task.
Task
This task is an alternative to the usual technique of linking an application against a static
import library for a Dynamic Link Library (DLL) that contains the required function
definitions.
A similar task can be used to dynamically load DBLIB on Unix platforms.
1. Your application must call db_init_dll to load the DBLIB DLL, and must call db_fini_dll
to free the DBLIB DLL. The db_init_dll call must be before any function in the database
interface, and no function in the interface can be called after db_fini_dll.
You must still call the db_init and db_fini library functions.
2. You must include the esqldll.h header file before the EXEC SQL INCLUDE SQLCA
statement or include sqlca.h in your embedded SQL program. The esqldll.h
header file includes sqlca.h.
3. A SQL OS macro must be defined. The header file sqlos.h, which is included by
sqlca.h, attempts to determine the appropriate macro and define it. However, certain
combinations of platforms and compilers may cause this to fail. In this case, you must add
a #define to the top of this file, or make the definition using a compiler option. The macro
that must be defined for Windows is shown below.
Macro Platforms
_SQL_OS_WINDOWS All Windows operating systems
4. Compile esqldll.c.
5. Instead of linking against the import library, link the object module esqldll.obj with
your embedded SQL application objects.
The DBLIB interface DLL loads dynamically when you run your embedded SQL application.
Programming 419
Embedded SQL
Prerequisites
There are no prerequisites for this task.
Task
The executable files and corresponding source code are located in the %ALLUSERSPROFILE
%\SybaseIQ\samples\SQLAnywhere\C directory.
The various commands manipulate a database cursor and print the query results on the screen.
Enter the letter of the command that you want to perform. Some systems may require you to
press Enter after the letter.
Programming 421
Embedded SQL
where table-name is a parameter passed to the routine. It then prepares a dynamic SQL
statement using this string.
The embedded SQL DESCRIBE statement is used to fill in the SQLDA structure with the
results of the SELECT statement.
Note: An initial guess is taken for the size of the SQLDA (3). If this is not big enough, the
actual size of the SELECT list returned by the database server is used to allocate a SQLDA of
the correct size.
The SQLDA structure is then filled with buffers to hold strings that represent the results of the
query. The fill_s_sqlda routine converts all data types in the SQLDA to DT_STRING and
allocates buffers of the appropriate size.
A cursor is then declared and opened for this statement. The rest of the routines for moving and
closing the cursor remain the same.
The fetch routine is slightly different: it puts the results into the SQLDA structure instead of
into a list of host variables. The print routine has changed significantly to print results from the
SQLDA structure up to the width of the screen. The print routine also uses the name fields of
the SQLDA to print headings for each column.
Prerequisites
There are no prerequisites for this task.
Task
The executable files and corresponding source code are located in the %ALLUSERSPROFILE
%\SybaseIQ\samples\SQLAnywhere\C directory. For Windows Mobile, an
additional example is located in the \SQLAnywhere\CE\esql_sample directory.
For Windows Mobile, use the esql_sample.sln project file for Microsoft Visual C
++. This file appears in SQLAnywhere\CE\esql_sample.
The various commands manipulate a database cursor and print the query results on the screen.
Enter the letter of the command that you want to perform. Some systems may require you to
press Enter after the letter.
Programming 423
Embedded SQL
The LONGVARCHAR structure can be used with more than 32767 bytes of data. Large
data can be fetched all at once, or in pieces using the GET DATA statement. Large data can
be supplied to the server all at once, or in pieces by appending to a database variable using
the SET statement. The data is not null-terminated or blank-padded.
• DT_LONGNVARCHAR – Long varying length character string, in the NCHAR
character set. The macro defines a structure, as follows:
typedef struct LONGVARCHAR {
a_sql_uint32 array_len; /* number of allocated bytes in array */
a_sql_uint32 stored_len; /* number of bytes stored in array
* (never larger than array_len) */
a_sql_uint32 untrunc_len;/* number of bytes in untruncated
expression
* (may be larger than array_len) */
char array[1]; /* the data */
} LONGVARCHAR, LONGNVARCHAR, LONGBINARY;
The LONGNVARCHAR structure can be used with more than 32767 bytes of data. Large
data can be fetched all at once, or in pieces using the GET DATA statement. Large data can
be supplied to the server all at once, or in pieces by appending to a database variable using
the SET statement. The data is not null-terminated or blank-padded.
• DT_BINARY – Varying length binary data with a two-byte length field. The maximum
length is 32765 bytes. When supplying information to the database server, you must set the
length field. When fetching information from the database server, the server sets the length
field.
typedef struct BINARY {
a_sql_ulen len;
char array[1];
} BINARY;
• DT_LONGBINARY – Long binary data. The macro defines a structure, as follows:
typedef struct LONGVARCHAR {
a_sql_uint32 array_len; /* number of allocated bytes in array */
a_sql_uint32 stored_len; /* number of bytes stored in array
* (never larger than array_len) */
a_sql_uint32 untrunc_len;/* number of bytes in untruncated
expression
* (may be larger than array_len) */
char array[1]; /* the data */
} LONGVARCHAR, LONGNVARCHAR, LONGBINARY;
The LONGBINARY structure may be used with more than 32767 bytes of data. Large data
can be fetched all at once, or in pieces using the GET DATA statement. Large data can be
supplied to the server all at once, or in pieces by appending to a database variable using the
SET statement.
• DT_TIMESTAMP_STRUCT – SQLDATETIME structure with fields for each part of a
timestamp.
typedef struct sqldatetime {
unsigned short year; /* for example 1999 */
unsigned char month; /* 0-11 */
unsigned char day_of_week; /* 0-6 0=Sunday */
unsigned short day_of_year; /* 0-365 */
unsigned char day; /* 1-31 */
unsigned char hour; /* 0-23 */
Programming 425
Embedded SQL
The SQLDATETIME structure can be used to retrieve fields of DATE, TIME, and
TIMESTAMP type (or anything that can be converted to one of these). Often, applications
have their own formats and date manipulation code. Fetching data in this structure makes it
easier for you to manipulate this data. DATE, TIME, and TIMESTAMP fields can also be
fetched and updated with any character type.
If you use a SQLDATETIME structure to enter a date, time, or timestamp into the
database, the day_of_year and day_of_week members are ignored.
• DT_VARIABLE – Null-terminated character string. The character string must be the
name of a SQL variable whose value is used by the database server. This data type is used
only for supplying data to the database server. It cannot be used when fetching data from
the database server.
The structures are defined in the sqlca.h file. The VARCHAR, NVARCHAR, BINARY,
DECIMAL, and LONG data types are not useful for declaring host variables because they
contain a one-character array. However, they are useful for allocating variables dynamically or
typecasting other variables.
These host variables can then be used in place of value constants in any SQL statement. When
the database server executes the statement, the value of the host variable is used. Host
variables cannot be used in place of table or column names: dynamic SQL is required for this.
The variable name is prefixed with a colon (:) in a SQL statement to distinguish it from other
identifiers allowed in the statement.
In the SQL preprocessor, C language code is only scanned inside a DECLARE SECTION. So,
TYPEDEF types and structures are not allowed, but initializers on the variables are allowed
inside a DECLARE SECTION.
Example
The following sample code illustrates the use of host variables on an INSERT statement. The
variables are filled in by the program and then inserted into the database:
EXEC SQL BEGIN DECLARE SECTION;
long employee_number;
char employee_name[50];
char employee_initials[8];
char employee_phone[15];
EXEC SQL END DECLARE SECTION;
/* program fills in variables with appropriate values
*/
EXEC SQL INSERT INTO Employees
VALUES (:employee_number, :employee_name,
:employee_initials, :employee_phone );
Programming 427
Embedded SQL
The preprocessor recognizes these macros within an embedded SQL declaration section and
treats the variable as the appropriate type. It is recommended that the DECIMAL
(DT_DECIMAL, DECL_DECIMAL) type not be used since the format of decimal numbers
is proprietary.
The following table lists the C variable types that are allowed for host variables and their
corresponding embedded SQL interface data types.
Programming 429
Embedded SQL
Character sets
For DT_FIXCHAR, DT_STRING, DT_VARCHAR, and DT_LONGVARCHAR, character
data is in the application's CHAR character set, which is usually the character set of the
application's locale. An application can change the CHAR character set either by using the
CHARSET connection parameter, or by calling the db_change_char_charset function.
For DT_NFIXCHAR, DT_NSTRING, DT_NVARCHAR, and DT_LONGNVARCHAR,
data is in the application's NCHAR character set. By default, the application's NCHAR
character set is the same as the CHAR character set. An application can change the NCHAR
character set by calling the db_change_nchar_charset function.
Data lengths
Regardless of the CHAR and NCHAR character sets in use, all data lengths are specified in
bytes.
If character set conversion occurs between the server and the application, it is the application's
responsibility to ensure that buffers are sufficiently large to handle the converted data, and to
issue additional GET DATA statements if data is truncated.
Pointers to char
The database interface considers a host variable declared as a pointer to char (char * a) to be
32767 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 someone 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. 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 technique allows the embedded SQL
statements to know the size of the array.
Programming 431
Embedded SQL
If used, these variables are set after any embedded SQL statement that makes a database
request (EXEC SQL statements other than DECLARE SECTION, INCLUDE, WHENEVER
SQLCODE, and so on). As a consequence, the SQLCODE and SQLSTATE host variables
must be visible in the scope of every embedded SQL statement that generates database
requests.
The following is valid embedded SQL:
EXEC SQL INCLUDE SQLCA;
// declare SQLCODE with global scope
EXEC SQL BEGIN DECLARE SECTION;
long SQLCODE;
EXEC SQL END DECLARE SECTION;
sub1() {
EXEC SQL BEGIN DECLARE SECTION;
char SQLSTATE[6];
EXEC SQL END DECLARE SECTION;
exec SQL CREATE TABLE ...
}
sub2() {
EXEC SQL BEGIN DECLARE SECTION;
char SQLSTATE[6];
EXEC SQL END DECLARE SECTION;
exec SQL DROP TABLE ...
}
The following is not valid embedded SQL because SQLSTATE is not defined in the scope of
the function sub2:
EXEC SQL INCLUDE SQLCA;
sub1() {
EXEC SQL BEGIN DECLARE SECTION;
char SQLSTATE[6];
EXEC SQL END DECLARE SECTION;
exec SQL CREATE TABLE...
}
sub2() {
exec SQL DROP TABLE...
}
Indicator Variables
Indicator variables are C variables that hold supplementary information when you are fetching
or putting data. There are several distinct uses for indicator variables:
• NULL values – To enable applications to handle NULL values.
• String truncation – To enable applications to handle cases when fetched values must be
truncated to fit into host variables.
• Conversion errors – To hold error information.
An indicator variable is a host variable of type a_sql_len that is placed immediately following
a regular host variable in a SQL statement. For example, in the following INSERT
statement, :ind_phone is an indicator variable:
EXEC SQL INSERT INTO Employees
VALUES (:employee_number, :employee_name,
:employee_initials, :employee_phone:ind_phone );
On a fetch or execute where no rows are received from the database server (such as when an
error or end of result set occurs), then indicator values are unchanged.
Note: To allow for the future use of 32 and 64-bit lengths and indicators, the use of short int for
embedded SQL indicator variables is deprecated. Use a_sql_len instead.
Programming 433
Embedded SQL
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.
SQLCA Fields
The fields in the SQLCA have the following meanings:
• sqlcaid – An 8-byte character field that contains the string SQLCA as an identification of
the SQLCA structure. This field helps in debugging when you are looking at memory
contents.
• sqlcabc – A 32-bit integer that contains the length of the SQLCA structure (136 bytes).
• sqlcode – A 32-bit integer that specifies the error code when the database detects an error
on a request. Definitions for the error codes can be found in the header file sqlerr.h.
The error code is 0 (zero) for a successful operation, positive for a warning, and negative
for an error.
• sqlerrml – The length of the information in the sqlerrmc field.
• sqlerrmc – Zero or more character strings to be inserted into an error message. Some error
messages contain one or more placeholder strings (%1, %2, ...) that are replaced with the
strings in this field.
For example, if a Table Not Found error is generated, sqlerrmc contains the table
name, which is inserted into the error message at the appropriate place.
Programming 435
Embedded SQL
• sqlerrp – Reserved.
• sqlerrd – A utility array of 32-bit integers.
• sqlwarn – Reserved.
• sqlstate – The SQLSTATE status value. The ANSI SQL standard defines this type of
return value from a SQL statement in addition to the SQLCODE value. The SQLSTATE
value is always a five-character null-terminated string, divided into a two-character class
(the first two characters) and a three-character subclass. Each character can be a digit from
0 through 9 or an uppercase alphabetic character A through Z.
Any class or subclass that begins with 0 through 4 or A through H is defined by the SQL
standard; other classes and subclasses are implementation defined. The SQLSTATE value
'00000' means that there has been no error or warning.
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 statement.
The database server does not set this number to zero for each statement. Your program can
set this variable to zero before executing a sequence of statements. After the last statement,
this number is the total number of input/output operations for the entire statement
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.
• OPEN and RESUME statements – On a cursor OPEN or RESUME, 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_counts option.
• FETCH cursor statement – The SQLCOUNT field is filled if a SQLE_NOTFOUND
warning is returned. It contains the number of rows by which a FETCH RELATIVE or
FETCH ABSOLUTE statement goes outside the range of possible cursor positions (a
cursor can be on a row, before the first row, or after the last row). For a wide fetch,
SQLCOUNT is the number of rows actually fetched, and is less than or equal to the
number of rows requested. During a wide fetch, SQLE_NOTFOUND is only set if no
rows are returned.
The value is 0 if the row was not found, but the position is valid, for example, executing
FETCH RELATIVE 1 when positioned on the last row of a cursor. The value is positive
if the attempted fetch was beyond the end of the cursor, and negative if the attempted
fetch was before the beginning of the cursor.
• GET DATA statement – The SQLCOUNT field holds the actual length of the value.
• DESCRIBE statement – If the WITH VARIABLE RESULT clause is used to
describe procedures that may have more than one result set, SQLCOUNT is set to one
of the following values:
• 0 – The result set may change: the procedure call should be described again
following each OPEN statement.
• 1 – The result set is fixed. No re-describing is required.
For the SQLE_SYNTAX_ERROR syntax error, the field contains the approximate
character position within the statement where the error was detected.
• sqlerrd[3] (SQLIOESTIMATE) – The estimated number of input/output operations that
are required to complete the statement. This field is given a value on an OPEN or
EXPLAIN statement.
#define TRUE 1
#define FALSE 0
// multithreading support
Programming 437
Embedded SQL
} a_thread_data;
int main()
{
int num_threads = 4;
int thread;
int num_iters = 300;
int num_done = 0;
a_thread_data *thread_data;
thread_data = (a_thread_data *)malloc( sizeof(a_thread_data) *
num_threads );
for( thread = 0; thread < num_threads; thread++ ) {
thread_data[ thread ].num_iters = num_iters;
thread_data[ thread ].thread = thread;
thread_data[ thread ].done = FALSE;
if( _beginthread( do_one_iter,
8096,
(void *)&thread_data[thread] ) <= 0 ) {
printf( "FAILED creating thread.\n" );
return( 1 );
}
}
while( num_done != num_threads ) {
Sleep( 1000 );
num_done = 0;
for( thread = 0; thread < num_threads; thread++ ) {
if( thread_data[ thread ].done == TRUE ) {
num_done++;
}
}
}
return( 0 );
}
Multiple SQLCAs
You must not use the SQL preprocessor option (-r-) that generates non-reentrant code.
Reentrant code is a little larger and a little slower because statically initialized global variables
cannot be used. However, these effects are minimal.
Each SQLCA used in your program must be initialized with a call to db_init and cleaned up at
the end with a call to db_fini.
The embedded SQL statement SET SQLCA is used to tell the SQL preprocessor to use a
different SQLCA for database requests. Usually, a statement such as EXEC SQL SET
SQLCA 'task_data->sqlca'; is used at the top of your program or in a header file to
set the SQLCA reference to point at task specific data. Performance is unaffected because this
statement does not generate any code. It changes the state within the preprocessor so that any
reference to the SQLCA uses the given string.
Each thread must have its own SQLCA. This requirement also applies to code in a shared
library (in a DLL, for example) that uses embedded SQL and is called by more than one thread
in your application.
You can use the multiple SQLCA support in any of the supported embedded SQL
environments, but it is only required in reentrant code.
You do not need to use multiple SQLCAs to connect to more than one database or have more
than one connection to a single database.
Each SQLCA can have one unnamed connection. Each SQLCA has an active or current
connection.
All operations on a given database connection must use the same SQLCA that was used when
the connection was established.
Note: Operations on different connections are subject to the normal record locking
mechanisms and may cause each other to block and possibly to deadlock.
Programming 439
Embedded SQL
...
sprintf( comm,
"UPDATE %s SET Street = :?, City = :?"
"WHERE EmployeeID = :?",
tablename );
EXEC SQL PREPARE S1 FROM :comm FOR UPDATE;
EXEC SQL EXECUTE S1 USING :street, :city:cityind, :empnum;
This method requires you 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 statement.
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 Street = :street, City = :city"
" WHERE EmployeeID = :empnum",
tablename );
EXEC SQL PREPARE S1 FROM :comm FOR UPDATE;
/* Assume that there are no more than 10 host variables.
* See next example if you cannot put a limit on it. */
sqlda = alloc_sqlda( 10 );
EXEC SQL DESCRIBE BIND VARIABLES FOR S1 INTO sqlda;
/* sqlda->sqld will tell you how many
host variables there were. */
/* Fill in SQLDA_VARIABLE fields with
values based on name fields in sqlda. */
...
EXEC SQL EXECUTE S1 USING DESCRIPTOR sqlda;
free_sqlda( sqlda );
SQLDA contents
The SQLDA consists of an array of variable descriptors. Each descriptor describes the
attributes of the corresponding C program variable or the location that the database stores data
into or retrieves data from:
data type
length if type is a string type
memory address
indicator variable
Programming 441
Embedded SQL
Note: To avoid consuming unnecessary resources, ensure that statements are dropped after
use.
struct sqlname {
short int length; /* length of char data */
char data[ SQL_MAX_NAME_LEN ]; /* data */
};
Programming 443
Embedded SQL
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 */
};
SQLDA Fields
The SQLDA fields have the following meanings:
Field Description
sqldaid An 8-byte character field that contains the string
SQLDA as an identification of the SQLDA struc-
ture. This field helps in debugging when you are
looking at memory contents.
Field Description
sqlvar An array of descriptors of type struct sqlvar, each
describing a host variable.
Programming 445
Embedded SQL
It is filled by a DESCRIBE statement and is not otherwise used. This field has a different
meaning for the two formats of the DESCRIBE statement:
• SELECT LIST – The name data buffer is filled with the column heading of the
corresponding item in the SELECT list.
• BIND VARIABLES – The name data buffer is filled with the name of the host variable
that was used as a bind variable, or "?" if an unnamed parameter marker is used.
On a DESCRIBE SELECT LIST statement, any indicator variables present are filled with
a flag indicating whether the SELECT list item is updatable or not. More information
about this flag can be found in the sqldef.h header file.
If the DESCRIBE statement is a DESCRIBE USER TYPES statement, then this field
holds the long name of the user-defined data type instead of the column. If the type is a base
type, the field is empty.
BINARY(n) DT_BINARY n
Database field type Embedded SQL type re- Length (in bytes) re-
turned turned on describe
BIT DT_BIT 1
DOUBLE DT_DOUBLE 8
FLOAT DT_FLOAT 4
INT DT_INT 4
Programming 447
Embedded SQL
Database field type Embedded SQL type re- Length (in bytes) re-
turned turned on describe
NCHAR(n) DT_FIXCHAR / DT_NFIX- n times maximum character
CHAR2 length in the client's NCHAR
character set. If this length
would be more than 32767
bytes, then the embedded SQL
type returned is DT_LONG-
NVARCHAR with a length of
32767 bytes.
REAL DT_FLOAT 4
SMALLINT DT_SMALLINT 2
TINYINT DT_TINYINT 1
Database field type Embedded SQL type re- Length (in bytes) re-
turned turned on describe
VARCHAR(n CHAR) DT_VARCHAR1 n times maximum character
length in the client's CHAR
character set. If this length
would be more than 32767, then
the embedded SQL type re-
turned is DT_LONGVARCH-
AR with length 32767.
1The type returned for CHAR and VARCHAR may be DT_LONGVARCHAR if the
maximum byte length in the client's CHAR character set is greater than 32767 bytes.
2The type returned for NCHAR and NVARCHAR may be DT_LONGNVARCHAR if the
maximum byte length in the client's NCHAR character set is greater than 32767 bytes.
NCHAR, NVARCHAR, and LONG NVARCHAR are described by default as either
DT_FIXCHAR, DT_VARCHAR, or DT_LONGVARCHAR, respectively. If the
db_change_nchar_charset function has been called, the types are described as
DT_NFIXCHAR, DT_NVARCHAR, and DT_LONGNVARCHAR, respectively.
Programming 449
Embedded SQL
Programming 451
Embedded SQL
Embedded SQL data What the program must How the database re-
type set length field to when turns length information
receiving after fetching a value
DT_TIME Length of buffer. null character at end of string.
Programming 453
Embedded SQL
Cursor positioning
A cursor is positioned in one of three places:
• On a row
• Before the first row
• After the last row
When a cursor is opened, it is positioned before the first row. The cursor position can be moved
using the FETCH statement. It can be positioned to an absolute position either from the start or
from the end of the query results. It can also be moved relative to the current cursor position.
There are special positioned versions of the UPDATE and DELETE statements that can be
used to update or delete the row at the current position of the cursor. If the cursor is positioned
before the first row or after the last row, an error is returned indicating that there is no
corresponding row in the cursor.
The PUT statement can be used to insert a row into a cursor.
Programming 455
Embedded SQL
where ARRAY nnn is the last item of the FETCH statement. The fetch count nnn can be a host
variable. The number of variables in the SQLDA must be the product of nnn and the number of
columns per row. The first row is placed in SQLDA variables 0 to (columns per row) - 1, and so
on.
Each column must be of the same type in each row of the SQLDA, or a
SQLDA_INCONSISTENT error is returned.
The server returns in SQLCOUNT the number of records that were fetched, which is always
greater than zero unless there is an error or warning. On a wide fetch, a SQLCOUNT of 1 with
no error condition indicates that one valid row has been fetched.
Example
The following example code illustrates the use of wide fetches. You can also find this code in
%ALLUSERSPROFILE%\SybaseIQ\samples\SQLAnywhere\esqlwidefetch
\widefetch.sqc.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sqldef.h"
EXEC SQL INCLUDE SQLCA;
Programming 457
Embedded SQL
if( SQLCOUNT == 0 )
{
rows_fetched = 1;
}
else
{
rows_fetched = SQLCOUNT;
}
printf( "Fetched %d Rows:\n", rows_fetched );
for( row = 0; row < rows_fetched; row++ )
{
for( col = 0; col < cols_per_row; col++ )
{
offset = row * cols_per_row + col;
printf( " \"%s\"",
(char *)sqlda->sqlvar[offset].sqldata );
}
printf( "\n" );
}
}
static int DoQuery(
char * query_str0,
unsigned fetch_width0 )
{
/* Wide Fetch "query_str0" select statement
* using a width of "fetch_width0" rows" */
SQLDA * sqlda;
unsigned cols_per_row;
EXEC SQL BEGIN DECLARE SECTION;
a_sql_statement_number stat;
char * query_str;
unsigned fetch_width;
EXEC SQL END DECLARE SECTION;
query_str = query_str0;
fetch_width = fetch_width0;
Programming 459
Embedded SQL
including the row that caused the warning. All remaining SQLDA items are marked as
NULL.
• If a row being fetched has been deleted or is locked, generating a
SQLE_NO_CURRENT_ROW or SQLE_LOCKED error, SQLCOUNT contains the
number of rows that were read before the error. This does not include the row that caused
the error. The SQLDA does not contain values for any of the rows since SQLDA values are
not returned on errors. The SQLCOUNT value can be used to reposition the cursor, if
necessary, to read the rows.
Prerequisites
There are no prerequisites for this task.
Task
Programming 461
Embedded SQL
• untrunc_len – The number of bytes that would be stored in the array if the value was
not truncated. Always greater than or equal to stored_len. If truncation occurs, this
value is larger than array_len.
Prerequisites
There are no prerequisites for this task.
Task
Prerequisites
There are no prerequisites for this task.
Task
The embedded SQL application is ready to send LONG values to the database.
Prerequisites
There are no prerequisites for this task.
Task
The embedded SQL application is ready to send LONG values to the database.
Programming 463
Embedded SQL
The following code fragment illustrates both creating and executing a stored procedure in
embedded SQL:
EXEC SQL CREATE PROCEDURE pettycash(
IN Amount DECIMAL(10,2) )
BEGIN
UPDATE account
SET balance = balance - Amount
WHERE name = 'bank';
UPDATE account
SET balance = balance + Amount
WHERE name = 'pettycash expense';
END;
EXEC SQL CALL pettycash( 10.72 );
To pass host variable values to a stored procedure or to retrieve the output variables, you
prepare and execute a CALL statement. The following code fragment illustrates the use of
host variables. Both the USING and INTO clauses are used on the EXECUTE statement.
EXEC SQL BEGIN DECLARE SECTION;
double hv_expense;
double hv_balance;
EXEC SQL END DECLARE SECTION;
// Code here
EXEC SQL CREATE PROCEDURE pettycash(
IN expense DECIMAL(10,2),
OUT endbalance DECIMAL(10,2) )
BEGIN
UPDATE account
SET balance = balance - expense
WHERE name = 'bank';
UPDATE account
SET balance = balance + expense
WHERE name = 'pettycash expense';
In this example, the procedure has been invoked with an OPEN statement rather than an
EXECUTE statement. The OPEN statement causes the procedure to execute until it reaches a
SELECT statement. At this point, C1 is a cursor for the SELECT statement within the
database procedure. You can use all forms of the FETCH statement (backward and forward
scrolling) until you are finished with it. The CLOSE statement stops execution of the
procedure.
If there had been another statement following the SELECT in the procedure, it would not have
been executed. To execute statements following a SELECT, use the RESUME cursor-name
statement. The RESUME statement either returns the warning
SQLE_PROCEDURE_COMPLETE or it returns SQLE_NOERROR indicating that there is
another cursor. The example illustrates a two-select procedure:
EXEC SQL CREATE PROCEDURE people()
RESULT( name char(50) )
BEGIN
SELECT GivenName || Surname
FROM Employees;
Programming 465
Embedded SQL
}
EXEC SQL CLOSE C1;
DESCRIBE ALL
DESCRIBE ALL describes IN, INOUT, OUT, and RESULT set parameters. DESCRIBE
ALL uses the indicator variables in the SQLDA to provide additional information.
The DT_PROCEDURE_IN and DT_PROCEDURE_OUT bits are set in the indicator
variable when a CALL statement is described. DT_PROCEDURE_IN indicates an IN or
INOUT parameter and DT_PROCEDURE_OUT indicates an INOUT or OUT parameter.
Procedure RESULT columns have both bits clear.
After a DESCRIBE OUTPUT, these bits can be used to distinguish between statements that
have result sets (need to use OPEN, FETCH, RESUME, CLOSE) and statements that do not
(need to use EXECUTE).
In your callback function, you cannot start another database request but you can cancel the
current request using the db_cancel_request function. You can use the db_is_working
function in your message handlers to determine if you have a database request in progress.
alloc_sqlda Function
Allocates a SQLDA with descriptors for numvar variables.
Syntax
struct sqlda * alloc_sqlda( unsigned numvar );
Parameters
• numvar – The number of variable descriptors to allocate.
Programming 467
Embedded SQL
Returns
Pointer to a SQLDA if successful and returns the null pointer if there is not enough memory
available.
Remarks
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 the
alloc_sqlda_noind function.
alloc_sqlda_noind Function
Allocates a SQLDA with descriptors for numvar variables.
Syntax
struct sqlda * alloc_sqlda_noind( unsigned numvar );
Parameters
• numvar – The number of variable descriptors to allocate.
Returns
Pointer to a SQLDA if successful and returns the null pointer if there is not enough memory
available.
Remarks
Allocates a SQLDA with descriptors for numvar variables. The sqln field of the SQLDA is
initialized to numvar. Space is not allocated for indicator variables; the indicator pointers are
set to the null pointer. A null pointer is returned if memory cannot be allocated.
db_backup Function
Although this function provides one way to add backup features to an application, the
recommended way to do this task is to use the BACKUP DATABASE statement.
Syntax
void db_backup(
SQLCA * sqlca,
int op,
int file_num,
unsigned long page_num,
struct sqlda * sqlda);
Parameters
• sqlca – A pointer to a SQLCA structure.
• op – The action or operation to be performed.
• file_num – The file number of the database.
• page_num – The page number of the database. A value in the range 0 to the maximum
number of pages less 1.
• sqlda – A pointer to a SQLDA structure.
Authorization
Must be connected as a user with BACKUP DATABASE system privilege, or have the
SYS_RUN_REPLICATION_ROLE system role.
Remarks
Although this function provides one way to add backup features to an application, the
recommended way to do this task is to use the BACKUP DATABASE statement.
The action performed depends on the value of the op parameter:
• DB_BACKUP_START – Must be called before a backup can start. Only one backup can
be running per database 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 database page size. Backups are processed one page at a time.
The file_num, page_num, and sqlda parameters are ignored.
• DB_BACKUP_OPEN_FILE – Open the database file specified by file_num, which
allows pages of the specified file to be backed up using DB_BACKUP_READ_PAGE.
Valid file numbers are 0 through DB_BACKUP_MAX_FILE for the root database files,
and 0 through DB_BACKUP_TRANS_LOG_FILE for the transaction log file. 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) that identifies the time that the database file was created, and the
operating system file name is in the sqlerrmc field of the SQLCA.
The page_num and sqlda parameters are ignored.
• DB_BACKUP_READ_PAGE – Read one page of the database file specified by
file_num. The page_num should be a value from 0 to one less than the number of pages
returned in SQLCOUNT by a successful call to db_backup with the
DB_BACKUP_OPEN_FILE operation. Otherwise, SQLCODE is set to
SQLE_NOTFOUND. The sqlda descriptor should be set up with one variable of type
DT_BINARY or DT_LONG_BINARY pointing to a buffer. The buffer should be large
enough to hold binary data of the size returned in the SQLCOUNT field on the call to
db_backup with the DB_BACKUP_START operation.
Programming 469
Embedded SQL
DT_BINARY data contains a two-byte length followed by the actual binary data, so the
buffer must be two bytes longer than the page size.
Note: This call makes a copy of the specified database page into the buffer, but it is up to
the application to save the buffer on some backup media.
• DB_BACKUP_READ_RENAME_LOG – This action is the same as
DB_BACKUP_READ_PAGE, except that after the last page of the transaction log has
been returned, the database server renames the transaction log and starts a new one.
If the database server is unable to rename the log at the current time (for example in version
7.0.x or earlier databases there may be incomplete transactions), the
SQLE_BACKUP_CANNOT_RENAME_LOG_YET error is set. In this case, do not use
the page returned, but instead reissue the request until you receive SQLE_NOERROR and
then write the page. Continue reading the pages until you receive the SQLE_NOTFOUND
condition.
The SQLE_BACKUP_CANNOT_RENAME_LOG_YET error may be returned multiple
times and on multiple pages. In your retry loop, you should add a delay so as not to slow the
server down with too many requests.
When you receive the SQLE_NOTFOUND condition, the transaction log has been backed
up successfully and the file has been renamed. The name for the old transaction file is
returned in the sqlerrmc field of the SQLCA.
You should check the sqlda->sqlvar[0].sqlind value after a db_backup call. If this value is
greater than zero, the last log page has been written and the log file has been renamed. The
new name is still in sqlca.sqlerrmc, but the SQLCODE value is SQLE_NOERROR.
You should not call db_backup again after this, except to close files and finish the backup.
If you do, you get a second copy of your backed up log file and you receive
SQLE_NOTFOUND.
• DB_BACKUP_CLOSE_FILE – Must be called when processing of one file is complete
to close the database file specified by file_num.
The page_num and sqlda parameters are ignored.
• DB_BACKUP_END – Must be called at the end of the backup. No other backup can start
until this backup has ended. Checkpoints are enabled again.
The file_num, page_num and sqlda parameters are ignored.
• DB_BACKUP_PARALLEL_START – Starts a parallel backup. Like
DB_BACKUP_START, only one backup can be running against a database at one time on
any given database server. Database checkpoints are disabled until the backup is complete
(until db_backup is called with an op value of DB_BACKUP_END). If the backup cannot
start, you receive SQLE_BACKUP_NOT_STARTED. Otherwise, the SQLCOUNT field
of the sqlca is set to the database page size.
The file_num parameter instructs the database server to rename the transaction log and
start a new one after the last page of the transaction log has been returned. If the value is
non-zero then the transaction log is renamed or restarted. Otherwise, it is not renamed and
restarted. This parameter eliminates the need for the
DB_BACKUP_READ_RENAME_LOG operation, which is not allowed during a
parallel backup operation.
The page_num parameter informs the database server of the maximum size of the client's
buffer, in database pages. On the server side, the parallel backup readers try to read
sequential blocks of pages—this value lets the server know how large to allocate these
blocks: passing a value of nnn lets the server know that the client is willing to accept at
most nnnn database pages at a time from the server. The server may return blocks of pages
of less than size nnn if it is unable to allocate enough memory for blocks of nnn pages. If
the client does not know the size of database pages until after the call to
DB_BACKUP_PARALLEL_START, this value can be provided to the server with the
DB_BACKUP_INFO operation. This value must be provided before the first call to
retrieve backup pages (DB_BACKUP_PARALLEL_READ).
Note: If you are using db_backup to start a parallel backup, db_backup does not create
writer threads. The caller of db_backup must receive the data and act as the writer.
• DB_BACKUP_INFO – This parameter provides additional information to the database
server about the parallel backup. The file_num parameter indicates the type of information
being provided, and the page_num parameter provides the value. You can specify the
following additional information with DB_BACKUP_INFO:
• DB_BACKUP_INFO_PAGES_IN_BLOCK – The page_num argument contains
the maximum number of pages that should be sent back in one block.
• DB_BACKUP_INFO_CHKPT_LOG – This is the client-side equivalent to the
WITH CHECKPOINT LOG option of the BACKUP DATABASE statement. A
page_num value of DB_BACKUP_CHKPT_COPY indicates COPY, while the value
DB_BACKUP_CHKPT_NOCOPY indicates NO COPY. If this value is not provided
it defaults to COPY.
• DB_BACKUP_PARALLEL_READ – This operation reads a block of pages from the
database server. Before invoking this operation, use the DB_BACKUP_OPEN_FILE
operation to open all the files that you want to back up.
DB_BACKUP_PARALLEL_READ ignores the file_num and page_num arguments.
The sqlda descriptor should be set up with one variable of type DT_LONGBINARY
pointing to a buffer. The buffer should be large enough to hold binary data of the size nnn
pages (specified in the DB_BACKUP_START_PARALLEL operation, or in a
DB_BACKUP_INFO operation).
The server returns a sequential block of database pages for a particular database file. The
page number of the first page in the block is returned in the SQLCOUNT field. The file
number that the pages belong to is returned in the SQLIOESTIMATE field, and this value
matches one of the file numbers used in the DB_BACKUP_OPEN_FILE calls. The size of
the data returned is available in the stored_len field of the DT_LONGBINARY variable,
and is always a multiple of the database page size. While the data returned by this call
contains a block of sequential pages for a given file, it is not safe to assume that separate
Programming 471
Embedded SQL
blocks of data are returned in sequential order, or that all of one database file's pages are
returned before another database file's pages. The caller should be prepared to receive
portions of another individual file out of sequential order, or of any opened database file on
any given call.
An application should make repeated calls to this operation until the size of the read data is
0, or the value of sqlda->sqlvar[0].sqlind is greater than 0. If the backup is started with
transaction log renaming/restarting, SQLERROR could be set to
SQLE_BACKUP_CANNOT_RENAME_LOG_YET. In this case, do not use the pages
returned, but instead reissue the request until you receive SQLE_NOERROR, and then
write the data. The SQLE_BACKUP_CANNOT_RENAME_LOG_YET error may be
returned multiple times and on multiple pages. In your retry loop, you should add a delay
so the database server is not slowed down by too many requests. Continue reading the
pages until either of the first two conditions are met.
The dbbackup utility uses the following algorithm. This is not C code, and does not include
error checking.
sqlda->sqld = 1;
sqlda->sqlvar[0].sqltype = DT_LONGBINARY
if SQLCODE != SQLE_NO_ERROR
break;
/* cleanup */
free page buffer
db_cancel_request Function
Cancels the currently active database server request. This function checks to make sure a
database server request is active before sending the cancel request.
Syntax
int db_cancel_request( SQLCA * sqlca );
Parameters
• sqlca – A pointer to a SQLCA structure.
Returns
1 when the cancel request is sent; 0 if no request is sent.
Remarks
A non-zero return value does not mean that the request was canceled. There are a few critical
timing cases where the cancel request and the response from the database or server cross. In
these cases, the cancel simply has no effect, even though the function still returns TRUE.
The db_cancel_request function can be called asynchronously. This function and
db_is_working are the only functions in the database interface library that can be called
asynchronously using a SQLCA that might be in use by another request.
If you cancel a request that is carrying out a cursor operation, the position of the cursor is
indeterminate. You must locate the cursor by its absolute position or close it, following the
cancel.
db_change_char_charset Function
Changes the application's CHAR character set for this connection.
Syntax
unsigned int db_change_char_charset(
SQLCA * sqlca,
char * charset );
Programming 473
Embedded SQL
Parameters
• sqlca – A pointer to a SQLCA structure.
• charset – A string representing the character set.
Returns
1 if the change is successful; 0 otherwise.
Remarks
Data sent and fetched using DT_FIXCHAR, DT_VARCHAR, DT_LONGVARCHAR, and
DT_STRING types are in the CHAR character set.
db_change_nchar_charset Function
Changes the application's NCHAR character set for this connection.
Syntax
unsigned int db_change_nchar_charset(
SQLCA * sqlca,
char * charset );
Parameters
• sqlca – A pointer to a SQLCA structure.
• charset – A string representing the character set.
Returns
1 if the change is successful; 0 otherwise.
Remarks
Data sent and fetched using DT_NFIXCHAR, DT_NVARCHAR, DT_LONGNVARCHAR,
and DT_NSTRING host variable types are in the NCHAR character set.
If the db_change_nchar_charset function is not called, all data is sent and fetched using the
CHAR character set. Typically, an application that wants to send and fetch Unicode data
should set the NCHAR character set to UTF-8.
If this function is called, the charset parameter is usually "UTF-8". The NCHAR character set
cannot be set to UTF-16.
In embedded SQL, NCHAR, NVARCHAR and LONG NVARCHAR are described as
DT_FIXCHAR, DT_VARCHAR, and DT_LONGVARCHAR, respectively, by default. If the
db_change_nchar_charset function has been called, these types are described as
DT_NFIXCHAR, DT_NVARCHAR, and DT_LONGNVARCHAR, respectively.
db_find_engine Function
Returns status information about the local database server.
Syntax
unsigned short db_find_engine(
SQLCA * sqlca,
char * name );
Parameters
• sqlca – A pointer to a SQLCA structure.
• name – NULL or a string containing the server's name.
Returns
Server status as an unsigned short value, or 0 if no server can be found over shared memory.
Remarks
Returns an unsigned short value, which indicates status information about the local database
server whose name is name. If no server can be found over shared memory with the specified
name, the return value is 0. A non-zero value indicates that the local server is currently
running.
If a null pointer is specified for name, information is returned about the default database
server.
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. Their meaning is
described below.
• DB_ENGINE – This flag is always set.
• DB_CLIENT – This flag is always set.
• DB_CAN_MULTI_DB_NAME – This flag is obsolete.
• DB_DATABASE_SPECIFIED – This flag is always set.
• DB_ACTIVE_CONNECTION – This flag is always set.
• DB_CONNECTION_DIRTY – This flag is obsolete.
• DB_CAN_MULTI_CONNECT – This flag is obsolete.
• DB_NO_DATABASES – This flag is set if the server has no databases started.
db_fini Function
This function frees resources used by the database interface or DLL.
Syntax
int db_fini( SQLCA * sqlca );
Programming 475
Embedded SQL
Parameters
• sqlca – A pointer to a SQLCA structure.
Returns
Non-zero value for success; 0 otherwise.
Remarks
You must not make any other library calls or execute any embedded SQL statements after
db_fini is called. If an error occurs during processing, the error code is set in SQLCA and the
function returns 0. If there are no errors, a non-zero value is returned.
You need to call db_fini once for each SQLCA being used.
The db_fini function should not be called directly or indirectly from the DllMain function in a
Windows Dynamic Link Library. The DllMain entry point function is intended to perform
only simple initialization and termination tasks. Calling db_fini can create deadlocks and
circular dependencies.
db_get_property Function
Obtains information about the database interface or the server to which you are connected.
Syntax
unsigned int db_get_property(
SQLCA * sqlca,
a_db_property property,
char * value_buffer,
int value_buffer_size );
Parameters
• sqlca – A pointer to a SQLCA structure.
• a_db_property – The property requested, either DB_PROP_CLIENT_CHARSET,
DB_PROP_SERVER_ADDRESS, or DB_PROP_DBLIB_VERSION.
• value_buffer – This argument is filled with the property value as a null-terminated string.
• value_buffer_size – The maximum length of the string value_buffer, including room for
the terminating null character.
Returns
1 if successful; 0 otherwise.
Remarks
The following properties are supported:
• DB_PROP_CLIENT_CHARSET – This property value gets the client character set (for
example, "windows-1252").
• DB_PROP_SERVER_ADDRESS – This property value gets the current connection's
server network address as a printable string. The shared memory protocol always returns
the empty string for the address. The TCP/IP protocol returns non-empty string addresses.
• DB_PROP_DBLIB_VERSION – This property value gets the database interface
library's version (for example, "16.0.0.1297").
db_init Function
This function initializes the database interface library.
Syntax
int db_init( SQLCA * sqlca );
Parameters
• sqlca – A pointer to a SQLCA structure.
Returns
Non-zero value if successful; 0 otherwise.
Remarks
This function must be called before any other library call is made and before any embedded
SQL statement is executed. The resources the interface library required for your program are
allocated and initialized on this call.
Use db_fini to free the resources at the end of your program. If there are any errors during
processing, they are returned in the SQLCA and 0 is returned. If there are no errors, a non-zero
value is returned and you can begin using embedded SQL statements and functions.
Usually, 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.
db_is_working Function
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.
Syntax
unsigned short db_is_working( SQLCA * sqlca );
Programming 477
Embedded SQL
Parameters
• sqlca – A pointer to a SQLCA structure.
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.
Remarks
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 a SQLCA
that might be in use by another request.
db_locate_servers Function
Provides programmatic access to the information displayed by the dblocate utility, listing all
the SAP Sybase IQ database servers on the local network that are listening on TCP/IP.
Syntax
unsigned int db_locate_servers(
SQLCA * sqlca,
SQL_CALLBACK_PARM callback_address,
void * callback_user_data );
Parameters
• sqlca – A pointer to a SQLCA structure.
• callback_address – The address of a callback function.
• callback_user_data – The address of a user-defined area in which to store data.
Returns
1 if successful; 0 otherwise.
Remarks
The callback function must have the following prototype:
int (*)( SQLCA * sqlca,
a_server_address * server_addr,
void * callback_user_data );
The callback function is called for each server found. If the callback function returns 0,
db_locate_servers stops iterating through servers.
The sqlca and callback_user_data passed to the callback function are those passed into
db_locate_servers. The second parameter is a pointer to an a_server_address structure.
a_server_address is defined in sqlca.h, with the following definition:
typedef struct a_server_address {
a_sql_uint32 port_type;
a_sql_uint32 port_num;
char *name;
char *address;
} a_server_address;
db_locate_servers_ex Function
Provides programmatic access to the information displayed by the dblocate utility, listing all
the SAP Sybase IQ database servers on the local network that are listening on TCP/IP, and
provides a mask parameter used to select addresses passed to the callback function.
Syntax
unsigned int db_locate_servers_ex(
SQLCA * sqlca,
SQL_CALLBACK_PARM callback_address,
void * callback_user_data,
unsigned int bitmask);
Parameters
• sqlca – A pointer to a SQLCA structure.
• callback_address – The address of a callback function.
• callback_user_data – The address of a user-defined area in which to store data.
• bitmask – A mask composed of any of DB_LOOKUP_FLAG_NUMERIC,
DB_LOOKUP_FLAG_ADDRESS_INCLUDES_PORT, or
DB_LOOKUP_FLAG_DATABASES.
Returns
1 if successful; 0 otherwise.
Remarks
The callback function must have the following prototype:
int (*)( SQLCA * sqlca,
a_server_address * server_addr,
void * callback_user_data );
The callback function is called for each server found. If the callback function returns 0,
db_locate_servers_ex stops iterating through servers.
The sqlca and callback_user_data passed to the callback function are those passed into
db_locate_servers. The second parameter is a pointer to an a_server_address structure.
a_server_address is defined in sqlca.h, with the following definition:
Programming 479
Embedded SQL
DB_LOOKUP_FLAG_NUMERIC
DB_LOOKUP_FLAG_ADDRESS_INCLUDES_PORT
DB_LOOKUP_FLAG_DATABASES
db_register_a_callback Function
This function registers callback functions.
Syntax
void db_register_a_callback(
SQLCA * sqlca,
a_db_callback_index index,
( SQL_CALLBACK_PARM ) callback );
Parameters
• sqlca – A pointer to a SQLCA structure.
• index – An index value identifying the type of callback as described below.
• callback – The address of a user-defined callback function.
Remarks
If you do not register a DB_CALLBACK_WAIT callback, the default action is to do nothing.
Your application blocks, waiting for the database response. You must register a callback for
the MESSAGE TO CLIENT statement.
To remove a callback, pass a null pointer as the callback function.
The following values are allowed for the index parameter:
• DB_CALLBACK_DEBUG_MESSAGE – The supplied function is called once for each
debug message and is passed a null-terminated string containing the text of the debug
message. A debug message is a message that is logged to the LogFile file. In order for a
debug message to be passed to this callback, the LogFile connection parameter must be
used. The string normally has a newline character (\n) immediately before the terminating
null character. The prototype of the callback function is as follows:
void SQL_CALLBACK debug_message_callback(
SQLCA * sqlca,
char * message_string );
• DB_CALLBACK_START – The prototype is as follows:
void SQL_CALLBACK start_callback( SQLCA * sqlca );
This function is called just before a database request is sent to the server.
DB_CALLBACK_START is used only on Windows.
• DB_CALLBACK_FINISH – The prototype is as follows:
void SQL_CALLBACK finish_callback( SQLCA * sqlca );
This function is called after the response to a database request has been received by the
DBLIB interface DLL. DB_CALLBACK_FINISH is used only on Windows operating
systems.
• DB_CALLBACK_CONN_DROPPED – The prototype is as follows:
void SQL_CALLBACK conn_dropped_callback (
SQLCA * sqlca,
char * conn_name );
This function is called when the database server is about to drop a connection because of a
liveness timeout, through a DROP CONNECTION statement, or because the database
server is being shut down. The connection name conn_name is passed in to allow you to
distinguish between connections. If the connection was not named, it has a value of NULL.
• DB_CALLBACK_WAIT – The prototype is as follows:
void SQL_CALLBACK wait_callback( SQLCA * sqlca );
This function is called repeatedly by the interface library while the database server or
client library is busy processing your database request.
You would register this callback as follows:
Programming 481
Embedded SQL
db_register_a_callback( &sqlca,
DB_CALLBACK_WAIT,
(SQL_CALLBACK_PARM)&db_wait_request );
• DB_CALLBACK_MESSAGE – This is used to enable the application to handle
messages received from the server during the processing of a request. Messages can be
sent to the client application from the database server using the SQL MESSAGE
statement. Messages can also be generated by long running database server statements.
The callback prototype is as follows:
void SQL_CALLBACK message_callback(
SQLCA * sqlca,
unsigned char msg_type,
an_sql_code code,
unsigned short length,
char * msg
);
The msg_type parameter states how important the message is. You may want to handle
different message types in different ways. The following possible values for msg_type are
defined in sqldef.h.
• MESSAGE_TYPE_INFO – The message type was INFO.
• MESSAGE_TYPE_WARNING – The message type was WARNING.
• MESSAGE_TYPE_ACTION – The message type was ACTION.
• MESSAGE_TYPE_STATUS – The message type was STATUS.
• MESSAGE_TYPE_PROGRESS – The message type was PROGRESS. This type of
message is generated by long running database server statements such as BACKUP
DATABASE and LOAD TABLE.
The code field may provide a SQLCODE associated with the message, otherwise the value
is 0. The length field tells you how long the message is. The message is not null-
terminated. SAP Sybase IQ DBLIB and ODBC clients can use the
DB_CALLBACK_MESSAGE parameter to receive progress messages.
For example, the Interactive SQL callback displays STATUS and INFO message on the
Messages tab, while messages of type ACTION and WARNING go to a window. 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.
When a message callback is not registered by the application, messages sent to the client
are saved to the log file when the LogFile connection parameter is specified. Also,
ACTION or STATUS messages sent to the client appear in a window on Windows
operating systems and are logged to stderr on Unix operating systems.
• DB_CALLBACK_VALIDATE_FILE_TRANSFER – This is used to register a file
transfer validation callback function. Before allowing any transfer to take place, the client
library will invoke the validation callback, if it exists. If the client data transfer is being
requested during the execution of indirect statements such as from within a stored
procedure, the client library will not allow a transfer unless the client application has
registered a validation callback. The conditions under which a validation call is made are
described more fully below.
The callback prototype is as follows:
int SQL_CALLBACK file_transfer_callback(
SQLCA * sqlca,
char * file_name,
int is_write
);
The file_name parameter is the name of the file to be read or written. The is_write
parameter is 0 if a read is requested (transfer from the client to the server), and non-zero for
a write. The callback function should return 0 if the file transfer is not allowed, non-zero
otherwise.
For data security, the server tracks the origin of statements requesting a file transfer. The
server determines if the statement was received directly from the client application. When
initiating the transfer of data from the client, the server sends the information about the
origin of the statement to the client software. On its part, the embedded SQL client library
allows unconditional transfer of data only if the data transfer is being requested due to the
execution of a statement sent directly by the client application. Otherwise, the application
must have registered the validation callback described above, in the absence of which the
transfer is denied and the statement fails with an error. If the client statement invokes a
stored procedure already existing in the database, then the execution of the stored
procedure itself is considered not to have been for a client initiated statement. However, if
the client application explicitly creates a temporary stored procedure then the execution of
the stored procedure results in the server treating the procedure as having been client
initiated. Similarly, if the client application executes a batch statement, then the execution
of the batch statement is considered as being done directly by the client application.
db_start_database Function
Starts the database on an existing server, if possible. Otherwise, a new server is started.
Syntax
unsigned int db_start_database( SQLCA * sqlca, char * parms );
Parameters
• sqlca – A pointer to a SQLCA structure.
• parms – A null-terminated string containing a semicolon-delimited list of parameter
settings, each of the form KEYWORD=value. For example:
"UID=DBA;PWD=sql;DBF=c:\\db\\mydatabase.db"
Programming 483
Embedded SQL
Returns
Non-zero if successful; 0 otherwise.
Remarks
The database is started on an existing server, if possible. Otherwise, a new server is started.
If the database was already running or was successfully started, the return value is true (non-
zero) and SQLCODE is set to 0. Error information is returned in the SQLCA.
If a user ID and password are supplied in the parameters, they are ignored.
The privilege required to start and stop a database is set on the server command line using the
-gd option.
db_start_engine Function
Starts the database server if it is not running.
Syntax
unsigned int db_start_engine( SQLCA * sqlca, char * parms );
Parameters
• sqlca – A pointer to a SQLCA structure.
• parms – A null-terminated string containing a semicolon-delimited list of parameter
settings, each of the form KEYWORD=value. For example:
"UID=DBA;PWD=sql;DBF=c:\\db\\mydatabase.db"
Returns
Non-zero if successful; 0 otherwise.
Remarks
If the database server was already running or was successfully started, the return value is
TRUE (non-zero) and SQLCODE is set to 0. Error information is returned in the SQLCA.
The following call to db_start_engine starts the database server, loads the specified database,
and names the server demo.
db_start_engine( &sqlca, "DBF=demo.db;START=iqsrv16" );
Unless the ForceStart (FORCE) connection parameter is used and set to YES, 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.
When the ForceStart connection is set to YES, there is no attempt to connect to a server before
trying to start one. This enables the following pair of commands to work as expected:
1. Start a database server named server_1:
If ForceStart (FORCE) is not used and the ServerName (Server) parameter is not used, then
the second command would have attempted to connect to server_1. The db_start_engine
function does not pick up the server name from the -n option of the StartLine (START)
parameter.
db_stop_database Function
Stop the database identified by DatabaseName (DBN) on the server identified by ServerName
(Server). If ServerName is not specified, the default server is used.
Syntax
unsigned int db_stop_database( SQLCA * sqlca, char * parms );
Parameters
• sqlca – A pointer to a SQLCA structure.
• parms – A null-terminated string containing a semicolon-delimited list of parameter
settings, each of the form KEYWORD=value. For example:
"UID=DBA;PWD=sql;DBF=c:\\db\\mydatabase.db"
Returns
Non-zero if successful; 0 otherwise.
Remarks
By default, this function does not stop a database that has existing connections. If
Unconditional (UNC) is set to yes, the database is stopped regardless of existing connections.
A return value of TRUE indicates that there were no errors.
The privilege required to start and stop a database is set on the server command line using the
-gd option.
db_stop_engine Function
Stops execution of the database server.
Syntax
unsigned int db_stop_engine( SQLCA * sqlca, char * parms );
Parameters
• sqlca – A pointer to a SQLCA structure.
Programming 485
Embedded SQL
Returns
Non-zero if successful; 0 otherwise.
Remarks
The steps carried out by this function are:
• Look for a local database server that has a name that matches the ServerName (Server)
parameter. If no ServerName is specified, look for the default local database server.
• If no matching server is found, this function returns with success.
• Send a request to the server to tell it to checkpoint and shut down all databases.
• Unload the database server.
By default, this function does not stop a database server that has existing connections. If the
Unconditional=yes connection parameter is specified, the database server is stopped
regardless of existing connections.
A C program can use this function instead of spawning dbstop. A return value of TRUE
indicates that there were no errors.
The use of db_stop_engine is subject to the privileges set with the -gk server option.
db_string_connect Function
Provides extra functionality beyond the embedded SQL CONNECT statement.
Syntax
unsigned int db_string_connect( SQLCA * sqlca, char * parms );
Parameters
• sqlca – A pointer to a SQLCA structure.
• parms – A null-terminated string containing a semicolon-delimited list of parameter
settings, each of the form KEYWORD=value. For example:
"UID=DBA;PWD=sql;DBF=c:\\db\\mydatabase.db"
Returns
Non-zero if successful; 0 otherwise.
Remarks
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
This function disconnects the connection identified by the ConnectionName parameter. All
other parameters are ignored.
Syntax
unsigned int db_string_disconnect(
SQLCA * sqlca,
char * parms );
Parameters
• sqlca – A pointer to a SQLCA structure.
• parms – A null-terminated string containing a semicolon-delimited list of parameter
settings, each of the form KEYWORD=value. For example:
"UID=DBA;PWD=sql;DBF=c:\\db\\mydatabase.db"
Returns
Non-zero if successful; 0 otherwise.
Remarks
If no ConnectionName parameter is specified in the string, the unnamed connection is
disconnected. This is equivalent to the embedded SQL DISCONNECT statement. The 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 connection
parameter and there are no other connections to the database. It also stops the server if it was
started with the AutoStop=yes parameter and there are no other databases running.
db_string_ping_server Function
This function can be used to determine if a server can be located, and optionally, if it a
successful connection to a database can be made.
Syntax
unsigned int db_string_ping_server(
SQLCA * sqlca,
char * connect_string,
unsigned int connect_to_db );
Parameters
• sqlca – A pointer to a SQLCA structure.
Programming 487
Embedded SQL
• connect_string – The connect_string is a normal connection string that may or may not
contain server and database information.
• connect_to_db – If connect_to_db is non-zero (TRUE), then the function attempts to
connect to a database on a server. It returns TRUE only if the connection string is sufficient
to connect to the named database on the named server.
If connect_to_db is zero, then the function only attempts to locate a server. It returns TRUE
only if the connection string is sufficient to locate a server. It makes no attempt to connect
to the database.
Returns
TRUE (non-zero) if the server or database was successfully located; FALSE (zero) otherwise.
Error information for locating the server or database is returned in the SQLCA.
db_time_change Function
This function permits clients to notify the server that the time has changed on the client.
Syntax
unsigned int db_time_change(
SQLCA * sqlca);
Parameters
• sqlca – A pointer to a SQLCA structure.
Returns
TRUE if successful; FALSE otherwise.
Remarks
This function recalculates the time zone adjustment and sends it to the server. On Windows
platforms, it is recommended that applications call this function when they receive the
WM_TIMECHANGE message. This will make sure that UTC timestamps are consistent over
time changes, time zone changes, or daylight savings time changeovers.
fill_s_sqlda Function
The same as fill_sqlda, except that it changes all the data types in sqlda to type DT_STRING.
Syntax
struct sqlda * fill_s_sqlda(
struct sqlda * sqlda,
unsigned int maxlen );
Parameters
• sqlda – A pointer to a SQLDA structure.
• maxlen – The maximum number of bytes to allocate for the string.
Returns
sqlda if successful and returns NULL if there is not enough memory available.
Remarks
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.
The SQLDA should be freed using the free_filled_sqlda function.
fill_sqlda Function
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.
Syntax
struct sqlda * fill_sqlda( struct sqlda * sqlda );
Parameters
• sqlda – A pointer to a SQLDA structure.
Returns
sqlda if successful and returns NULL if there is not enough memory available.
Remarks
Enough space is allocated for the database type and length indicated in the descriptor.
The SQLDA should be freed using the free_filled_sqlda function.
fill_sqlda_ex Function
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.
Syntax
struct sqlda * fill_sqlda_ex( struct sqlda * sqlda , unsigned int
flags);
Programming 489
Embedded SQL
Parameters
• sqlda – A pointer to a SQLDA structure.
• flags – 0 or FILL_SQLDA_FLAG_RETURN_DT_LONG
Returns
sqlda if successful and returns NULL if there is not enough memory available.
Remarks
Enough space is allocated for the database type and length indicated in the descriptor.
The SQLDA should be freed using the free_filled_sqlda function.
One flag bit is supported: FILL_SQLDA_FLAG_RETURN_DT_LONG. This flag is defined
in sqlca.h.
FILL_SQLDA_FLAG_RETURN_DT_LONG preserves DT_LONGVARCHAR,
DT_LONGNVARCHAR and DT_LONGBINARY types in the filled descriptor. If this flag
bit is not specified, fill_sqlda_ex converts DT_LONGVARCHAR, DT_LONGNVARCHAR
and DT_LONGBINARY types to DT_VARCHAR, DT_NVARCHAR and DT_BINARY
respectively. Using DT_LONGxyz types makes it possible to fetch 32767 bytes, not the 32765
bytes that DT_VARCHAR, DT_NVARCHAR and DT_BINARY are limited to.
fill_sqlda( sqlda ) is equivalent to fill_sqlda_ex( sqlda, 0 ).
free_filled_sqlda Function
Free the memory allocated to each sqldata pointer and the space allocated for the SQLDA
itself. Any null pointer is not freed.
Syntax
void free_filled_sqlda( struct sqlda * sqlda );
Parameters
• sqlda – A pointer to a SQLDA structure.
Remarks
This should only be called if fill_sqlda, fill_sqlda_ex, or fill_s_sqlda was used to allocate the
sqldata fields of the SQLDA.
Calling this function causes free_sqlda to be called automatically, and so any descriptors
allocated by alloc_sqlda are freed.
free_sqlda Function
Free space allocated to this sqlda and free the indicator variable space, as allocated in
fill_sqlda.
Syntax
void free_sqlda( struct sqlda * sqlda );
Parameters
• sqlda – A pointer to a SQLDA structure.
Remarks
Do not free the memory referenced by each sqldata pointer.
free_sqlda_noind Function
Free space allocated to this sqlda. Do not free the memory referenced by each sqldata pointer.
The indicator variable pointers are ignored.
Syntax
void free_sqlda_noind( struct sqlda * sqlda );
Parameters
• sqlda – A pointer to a SQLDA structure.
sql_needs_quotes Function
This function formulates a request to the database server to determine if quotes are needed.
Relevant information is stored in the sqlcode field.
Syntax
unsigned int sql_needs_quotes( SQLCA *sqlca, char * str );
Parameters
• sqlca – A pointer to a SQLCA structure.
• str – A string of characters that is a candidate for a SQL identifier.
Returns
TRUE or FALSE indicating whether the string requires double quotes around it when it is used
as a SQL identifier.
Remarks
There are three cases of return value/code combinations:
Programming 491
Embedded SQL
sqlda_storage Function
An unsigned 32-bit integer value representing the amount of storage required to store any
value for the varno variable.
Syntax
a_sql_uint32 sqlda_storage( struct sqlda * sqlda, int varno );
Parameters
• sqlda – A pointer to a SQLDA structure.
• varno – An index for a sqlvar host variable.
Returns
An unsigned 32-bit integer value representing the amount of storage required to store any
value for the variable.
sqlda_string_length Function
Returns an unsigned 32-bit integer value representing 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).
Syntax
a_sql_uint32 sqlda_string_length( struct sqlda * sqlda, int
varno );
Parameters
• sqlda – A pointer to a SQLDA structure.
• varno – An index for a sqlvar host variable.
Returns
An unsigned 32-bit integer value representing the length of the C string (type DT_STRING)
that would be required to hold the variable sqlda->sqlvar[varno] (no matter what its type is).
sqlerror_message Function
Returns 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.
Syntax
char * sqlerror_message( SQLCA * sqlca, char * buffer, int max );
Parameters
• sqlca – A pointer to a SQLCA structure.
• buffer – The buffer in which to place the message (up to max characters).
• max – The maximum length of the buffer.
Returns
A pointer to a string that contains an error message or NULL if no error was indicated.
Programming 493
Embedded SQL
• DESCRIBE statement [ESQL] – describe the host variables for a particular SQL
statement.
• DISCONNECT statement [ESQL] [Interactive SQL] – disconnect from database
server.
• DROP STATEMENT statement [ESQL] – free resources used by a prepared statement.
• EXECUTE statement [ESQL] – execute a particular SQL statement.
• EXPLAIN statement [ESQL] – explain the optimization strategy for a particular cursor.
• FETCH statement [ESQL] [SP] – fetch a row from a cursor.
• GET DATA statement [ESQL] – fetch long values from a cursor.
• GET DESCRIPTOR statement [ESQL] – retrieve information about a variable in a
SQLDA.
• GET OPTION statement [ESQL] – get the setting for a particular database option.
• INCLUDE statement [ESQL] – include a file for SQL preprocessing.
• OPEN statement [ESQL] [SP] – open a cursor.
• PREPARE statement [ESQL] – prepare a particular SQL statement.
• PUT statement [ESQL] – insert a row into a cursor.
• SET CONNECTION statement [Interactive SQL] [ESQL] – change active
connection.
• SET DESCRIPTOR statement [ESQL] – describe the variables in a SQLDA and place
data into the SQLDA.
• SET SQLCA statement [ESQL] – use a SQLCA other than the default global one.
• UPDATE (positioned) statement [ESQL] [SP] – update the row at the current location of
a cursor.
• WHENEVER statement [ESQL] – specify actions to occur on errors in SQL statements.
Syntax
public sacapi_i32 sqlany_affected_rows ( a_sqlany_stmt *
sqlany_stmt)
Parameters
• sqlany_stmt – A statement that was prepared and executed successfully with no result set
returned. For example, an INSERT, UPDATE or DELETE statement was executed.
Returns
The number of rows affected or -1 on failure.
Syntax
public sacapi_bool sqlany_bind_param ( a_sqlany_stmt *
sqlany_stmt, sacapi_u32 index, a_sqlany_bind_param * param)
Parameters
• sqlany_stmt – A statement prepared successfully using sqlany_prepare().
• index – The index of the parameter. This number must be between 0 and
sqlany_num_params() - 1.
• param – A a_sqlany_bind_param structure description of the parameter to be bound.
Programming 495
SAP Sybase IQ Database API for C/C++
Returns
1 on success or 0 on unsuccessful.
Syntax
public void sqlany_cancel ( a_sqlany_connection * sqlany_conn)
Parameters
• sqlany_conn – A connection object with a connection established using
sqlany_connect().
Syntax
public void sqlany_clear_error ( a_sqlany_connection *
sqlany_conn)
Parameters
• sqlany_conn – A connection object returned from sqlany_new_connection().
Syntax
public sacapi_bool sqlany_client_version (char * buffer, size_t
len)
Parameters
• buffer – The buffer to be filled with the client version string.
• len – The length of the buffer supplied.
Returns
1 when successful or 0 when unsuccessful.
Usage
This method fills the buffer passed with the major, minor, patch, and build number of the client
library. The buffer will be null-terminated.
sqlany_client_version_ex( a_sqlany_interface_context *,
char *, size_t) method
Returns the current client version.
Syntax
public sacapi_bool sqlany_client_version_ex
( a_sqlany_interface_context * context, char * buffer, size_t
len)
Parameters
• context – object that was create with sqlany_init_ex()
• buffer – The buffer to be filled with the client version string.
• len – The length of the buffer supplied.
Returns
1 when successful or 0 when unsuccessful.
Usage
This method fills the buffer passed with the major, minor, patch, and build number of the client
library. The buffer will be null-terminated.
Syntax
public sacapi_bool sqlany_commit ( a_sqlany_connection *
sqlany_conn)
Programming 497
SAP Sybase IQ Database API for C/C++
Parameters
• sqlany_conn – The connection object on which the commit operation is performed.
Returns
1 when successful or 0 when unsuccessful.
Syntax
public sacapi_bool sqlany_connect ( a_sqlany_connection *
sqlany_conn, const char * str)
Parameters
• sqlany_conn – A connection object created by sqlany_new_connection().
• str – A SQL Anywhere connection string.
Returns
1 if the connection is established successfully or 0 when the connection fails. Use
sqlany_error() to retrieve the error code and message.
Usage
The supplied connection object must first be allocated using sqlany_new_connection().
The following example demonstrates how to retrieve the error code of a failed connection
attempt:
a_sqlany_connection * sqlany_conn;
sqlany_conn = sqlany_new_connection();
if( !sqlany_connect( sqlany_conn, "uid=dba;pwd=sql" ) ) {
char reason[SACAPI_ERROR_SIZE];
sacapi_i32 code;
code = sqlany_error( sqlany_conn, reason, sizeof(reason) );
printf( "Connection failed. Code: %d Reason: %s\n", code,
reason );
} else {
printf( "Connected successfully!\n" );
sqlany_disconnect( sqlany_conn );
}
sqlany_free_connection( sqlany_conn );
For more information on connecting to a SQL Anywhere database server, see Connection
parameters and SQL Anywhere database connections.
sqlany_describe_bind_param( a_sqlany_stmt *,
sacapi_u32 , a_sqlany_bind_param *) method
Describes the bind parameters of a prepared statement.
Syntax
public sacapi_bool sqlany_describe_bind_param ( a_sqlany_stmt
* sqlany_stmt, sacapi_u32 index, a_sqlany_bind_param * param)
Parameters
• sqlany_stmt – A statement prepared successfully using sqlany_prepare().
• index – The index of the parameter. This number must be between 0 and
sqlany_num_params() - 1.
• param – A a_sqlany_bind_param structure that is populated with information.
Returns
1 when successful or 0 when unsuccessful.
Usage
This function allows the caller to determine information about prepared statement parameters.
The type of prepared statement, stored procedured or a DML, determines the amount of
information provided. The direction of the parameters (input, output, or input-output) are
always provided.
Syntax
public sacapi_bool sqlany_disconnect ( a_sqlany_connection *
sqlany_conn)
Parameters
• sqlany_conn – A connection object with a connection established using
sqlany_connect().
Programming 499
SAP Sybase IQ Database API for C/C++
Returns
1 when successful or 0 when unsuccessful.
Usage
All uncommitted transactions are rolled back.
Syntax
public sacapi_i32 sqlany_error ( a_sqlany_connection *
sqlany_conn, char * buffer, size_t size)
Parameters
• sqlany_conn – A connection object returned from sqlany_new_connection().
• buffer – A buffer to be filled with the error message.
• size – The size of the supplied buffer.
Returns
The last error code. Positive values are warnings, negative values are errors, and 0 indicates
success.
Usage
For more information on SQLCODE error messages, see SQL Anywhere error messages
sorted by SQLCODE.
Syntax
public sacapi_bool sqlany_execute ( a_sqlany_stmt *
sqlany_stmt)
Parameters
• sqlany_stmt – A statement prepared successfully using sqlany_prepare().
Returns
1 if the statement is executed successfully or 0 on failure.
Usage
You can use sqlany_num_cols() to verify if the executed statement returned a result set.
The following example shows how to execute a statement that does not return a result set:
a_sqlany_stmt * stmt;
int i;
a_sqlany_bind_param param;
Syntax
public a_sqlany_stmt * sqlany_execute_direct
( a_sqlany_connection * sqlany_conn, const char * sql_str)
Programming 501
SAP Sybase IQ Database API for C/C++
Parameters
• sqlany_conn – A connection object with a connection established using
sqlany_connect().
• sql_str – A SQL string. The SQL string should not have parameters such as ?.
Returns
A statement handle if the function executes successfully, NULL when the function executes
unsuccessfully.
Usage
Use this method if you want to prepare and execute a statement, or instead of calling
sqlany_prepare() followed by sqlany_execute().
The following example shows how to execute a statement that returns a result set:
a_sqlany_stmt * stmt;
Note: This function cannot be used for executing a SQL statement with parameters.
Syntax
public sacapi_bool sqlany_execute_immediate
( a_sqlany_connection * sqlany_conn, const char * sql)
Parameters
• sqlany_conn – A connection object with a connection established using
sqlany_connect().
• sql – A string representing the SQL statement to be executed.
Returns
1 on success or 0 on failure.
Usage
This function is useful for SQL statements that do not return a result set.
Syntax
public sacapi_bool sqlany_fetch_absolute ( a_sqlany_stmt *
sqlany_stmt, sacapi_i32 row_num)
Parameters
• sqlany_stmt – A statement object that was executed by sqlany_execute() or
sqlany_execute_direct().
• row_num – The row number to be fetched. The first row is 1, the last row is -1.
Returns
1 if the fetch was successfully, 0 when the fetch is unsuccessful.
Syntax
public sacapi_bool sqlany_fetch_next ( a_sqlany_stmt *
sqlany_stmt)
Programming 503
SAP Sybase IQ Database API for C/C++
Parameters
• sqlany_stmt – A statement object that was executed by sqlany_execute() or
sqlany_execute_direct().
Returns
1 if the fetch was successfully, 0 when the fetch is unsuccessful.
Usage
This function fetches the next row from the result set. When the result object is first created,
the current row pointer is set to before the first row, that is, row 0. This function first advances
the row pointer and then fetches the data at the new row.
sqlany_finalize_interface( SQLAnywhereInterface *)
method
Unloads the C API DLL library and resets the SQLAnywhereInterface structure.
Syntax
public void sqlany_finalize_interface ( SQLAnywhereInterface *
api)
Parameters
• api – An initialized structure to finalize.
Usage
Use the following statement to include the function prototype:
#include "sacapidll.h"
Use this method to finalize and free resources associated with the SQL Anywhere C API
DLL.
Examples of how the sqlany_finalize_interface method is used can be found in the C API
examples in the sdk\dbcapi\examples directory of your SQL Anywhere installation.
sqlany_fini() method
Finalizes the interface.
Syntax
public void sqlany_fini ()
Usage
Frees any resources allocated by the API.
Syntax
public void sqlany_fini_ex ( a_sqlany_interface_context *
context)
Parameters
• context – A context object that was returned from sqlany_init_ex()
Syntax
public void sqlany_free_connection ( a_sqlany_connection *
sqlany_conn)
Parameters
• sqlany_conn – A connection object created with sqlany_new_connection().
Programming 505
SAP Sybase IQ Database API for C/C++
Syntax
public void sqlany_free_stmt ( a_sqlany_stmt * sqlany_stmt)
Parameters
• sqlany_stmt – A statement object returned by the successful execution of
sqlany_prepare() or sqlany_execute_direct().
sqlany_get_bind_param_info( a_sqlany_stmt *,
sacapi_u32 , a_sqlany_bind_param_info *) method
Retrieves information about the parameters that were bound using sqlany_bind_param().
Syntax
public sacapi_bool sqlany_get_bind_param_info ( a_sqlany_stmt
* sqlany_stmt, sacapi_u32 index, a_sqlany_bind_param_info * info)
Parameters
• sqlany_stmt – A statement prepared successfully using sqlany_prepare().
• index – The index of the parameter. This number should be between 0 and
sqlany_num_params() - 1.
• info – A sqlany_bind_param_info buffer to be populated with the bound parameter's
information.
Returns
1 on success or 0 on failure.
Syntax
public sacapi_bool sqlany_get_column ( a_sqlany_stmt *
sqlany_stmt, sacapi_u32 col_index, a_sqlany_data_value * buffer)
Parameters
• sqlany_stmt – A statement object executed by sqlany_execute() or
sqlany_execute_direct().
• col_index – The number of the column to be retrieved. A column number is between 0 and
sqlany_num_cols() - 1.
• buffer – A a_sqlany_data_value object to be filled with the data fetched for column
col_index.
Returns
1 on success or 0 for failure. A failure can happen if any of the parameters are invalid or if there
is not enough memory to retrieve the full value from the SQL Anywhere database server.
Usage
For A_BINARY and A_STRING * data types, value->buffer points to an internal buffer
associated with the result set. Do not rely upon or alter the content of the pointer buffer as it
changes when a new row is fetched or when the result set object is freed. Users should copy the
data out of those pointers into their own buffers.
The value->length field indicates the number of valid characters that value->buffer points to.
The data returned in value->buffer is not null-terminated. This function fetches all the
returned values from the SQL Anywhere database server. For example, if the column contains
a blob, this function attempts to allocate enough memory to hold that value. If you do not want
to allocate memory, use sqlany_get_data() instead.
Programming 507
SAP Sybase IQ Database API for C/C++
Syntax
public sacapi_bool sqlany_get_column_info ( a_sqlany_stmt *
sqlany_stmt, sacapi_u32 col_index, a_sqlany_column_info * buffer)
Parameters
• sqlany_stmt – A statement object created by sqlany_prepare() or
sqlany_execute_direct().
• col_index – The column number between 0 and sqlany_num_cols() - 1.
• buffer – A column info structure to be filled with column information.
Returns
1 on success or 0 if the column index is out of range, or if the statement does not return a result
set.
Syntax
public sacapi_i32 sqlany_get_data ( a_sqlany_stmt * sqlany_stmt,
sacapi_u32 col_index, size_t offset, void * buffer, size_t size)
Parameters
• sqlany_stmt – A statement object executed by sqlany_execute() or
sqlany_execute_direct().
• col_index – The number of the column to be retrieved. A column number is between 0 and
sqlany_num_cols() - 1.
• offset – The starting offset of the data to get.
• buffer – A buffer to be filled with the contents of the column. The buffer pointer must be
aligned correctly for the data type copied into it.
• size – The size of the buffer in bytes. The function fails if you specify a size greater than
2^31 - 1.
Returns
The number of bytes successfully copied into the supplied buffer. This number must not
exceed 2^31 - 1. 0 indicates that no data remains to be copied. -1 indicates a failure.
Syntax
public sacapi_bool sqlany_get_data_info ( a_sqlany_stmt *
sqlany_stmt, sacapi_u32 col_index, a_sqlany_data_info * buffer)
Parameters
• sqlany_stmt – A statement object executed by sqlany_execute() or
sqlany_execute_direct().
• col_index – The column number between 0 and sqlany_num_cols() - 1.
• buffer – A data info buffer to be filled with the metadata about the data fetched.
Returns
1 on success, and 0 on failure. Failure is returned when any of the supplied parameters are
invalid.
Syntax
public sacapi_bool sqlany_get_next_result ( a_sqlany_stmt *
sqlany_stmt)
Parameters
• sqlany_stmt – A statement object executed by sqlany_execute() or
sqlany_execute_direct().
Programming 509
SAP Sybase IQ Database API for C/C++
Returns
1 if the statement successfully advances to the next result set, 0 otherwise.
Usage
If a query (such as a call to a stored procedure) returns multiple result sets, then this function
advances from the current result set to the next.
The following example demonstrates how to advance to the next result set in a multiple result
set query:
Syntax
public sacapi_bool sqlany_init (const char * app_name,
sacapi_u32 api_version, sacapi_u32 * version_available)
Parameters
• app_name – A string that names the application that is using the API. For example,
"PHP", "PERL", or "RUBY".
• api_version – The version of the compiled application.
• version_available – An optional argument to return the maximum supported API version.
Returns
1 on success, 0 otherwise
Usage
The following example demonstrates how to initialize the SQL Anywhere C API DLL:
sacapi_u32 api_version;
if( sqlany_init( "PHP", SQLANY_API_VERSION_1, &api_version ) ) {
printf( "Interface initialized successfully!\n" );
} else {
printf( "Failed to initialize the interface! Supported version=
%d\n", api_version );
}
Syntax
public a_sqlany_interface_context * sqlany_init_ex (const char
* app_name, sacapi_u32 api_version, sacapi_u32 * version_available)
Parameters
• app_name – A string that names the API used, for example "PHP", "PERL", or "RUBY".
• api_version – The current API version that the application is using. This should normally
be one of the SQLANY_API_VERSION_* macros
• version_available – An optional argument to return the maximum API version that is
supported.
Returns
a context object on success and NULL on failure.
Syntax
public int sqlany_initialize_interface ( SQLAnywhereInterface
* api, const char * optional_path_to_dll)
Parameters
• api – An API structure to initialize.
• optional_path_to_dll – An optional argument that specifies a path to the SQL Anywhere
C API DLL.
Returns
1 on successful initialization, and 0 on failure.
Programming 511
SAP Sybase IQ Database API for C/C++
Usage
Use the following statement to include the function prototype:
#include "sacapidll.h"
This function attempts to load the SQL Anywhere C API DLL dynamically and looks up all
the entry points of the DLL. The fields in the SQLAnywhereInterface structure are populated
to point to the corresponding functions in the DLL. If the optional path argument is NULL, the
environment variable SQLANY_DLL_PATH is checked. If the variable is set, the library
attempts to load the DLL specified by the environment variable. If that fails, the interface
attempts to load the DLL directly (this relies on the environment being setup correctly).
Examples of how the sqlany_initialize_interface method is used can be found in the C API
examples in the sdk\dbcapi\examples directory of your SQL Anywhere installation.
sqlany_make_connection(void *) method
Creates a connection object based on a supplied DBLIB SQLCA pointer.
Syntax
public a_sqlany_connection * sqlany_make_connection (void *
arg)
Parameters
• arg – A void * pointer to a DBLIB SQLCA object.
Returns
A connection object.
sqlany_make_connection_ex( a_sqlany_interface_context
*, void *) method
Creates a connection object based on a supplied DBLIB SQLCA pointer and context.
Syntax
public a_sqlany_connection * sqlany_make_connection_ex
( a_sqlany_interface_context * context, void * arg)
Parameters
• context – A valid context object that was created by sqlany_init_ex()
Returns
A connection object.
sqlany_new_connection(void) method
Creates a connection object.
Syntax
public a_sqlany_connection * sqlany_new_connection (void )
Returns
A connection object
Usage
You must create an API connection object before establishing a database connection. Errors
can be retrieved from the connection object. Only one request can be processed on a
connection at a time. In addition, not more than one thread is allowed to access a connection
object at a time. Undefined behavior or a failure occurs when multiple threads attempt to
access a connection object simultaneously.
sqlany_new_connection_ex( a_sqlany_interface_context *)
method
Creates a connection object using a context.
Syntax
public a_sqlany_connection * sqlany_new_connection_ex
( a_sqlany_interface_context * context)
Parameters
• context – A context object that was returned from sqlany_init_ex()
Returns
A connection object
Programming 513
SAP Sybase IQ Database API for C/C++
Syntax
public sacapi_i32 sqlany_num_cols ( a_sqlany_stmt *
sqlany_stmt)
Parameters
• sqlany_stmt – A statement object created by sqlany_prepare() or
sqlany_execute_direct().
Returns
The number of columns in the result set or -1 on a failure.
Syntax
public sacapi_i32 sqlany_num_params ( a_sqlany_stmt *
sqlany_stmt)
Parameters
• sqlany_stmt – A statement object returned by the successful execution of
sqlany_prepare().
Returns
The expected number of parameters, or -1 if the statement object is not valid.
Syntax
public sacapi_i32 sqlany_num_rows ( a_sqlany_stmt *
sqlany_stmt)
Parameters
• sqlany_stmt – A statement object that was executed by sqlany_execute() or
sqlany_execute_direct().
Returns
The number rows in the result set. If the number of rows is an estimate, the number returned is
negative and the estimate is the absolute value of the returned integer. The value returned is
positive if the number of rows is exact.
Usage
By default this function only returns an estimate. To return an exact count, set the row_counts
option on the connection. For more information on the row_counts option, see row_counts
option [database].
Syntax
public a_sqlany_stmt * sqlany_prepare ( a_sqlany_connection *
sqlany_conn, const char * sql_str)
Parameters
• sqlany_conn – A connection object with a connection established using
sqlany_connect().
• sql_str – The SQL statement to be prepared.
Returns
A handle to a SQL Anywhere statement object. The statement object can be used by
sqlany_execute() to execute the statement.
Usage
Execution does not happen until sqlany_execute() is called. The returned statement object
should be freed using sqlany_free_stmt().
The following statement demonstrates how to prepare a SELECT SQL string:
char * str;
a_sqlany_stmt * stmt;
Programming 515
SAP Sybase IQ Database API for C/C++
Syntax
public sacapi_bool sqlany_reset ( a_sqlany_stmt * sqlany_stmt)
Parameters
• sqlany_stmt – A statement prepared successfully using sqlany_prepare().
Returns
1 on success, 0 on failure.
Syntax
public sacapi_bool sqlany_rollback ( a_sqlany_connection *
sqlany_conn)
Parameters
• sqlany_conn – The connection object on which the rollback operation is to be performed.
Returns
1 on success, 0 otherwise.
Syntax
public sacapi_bool sqlany_send_param_data ( a_sqlany_stmt *
sqlany_stmt, sacapi_u32 index, char * buffer, size_t size)
Parameters
• sqlany_stmt – A statement prepared successfully using sqlany_prepare().
• index – The index of the parameter. This should be a number between 0 and
sqlany_num_params() - 1.
• buffer – The data to be sent.
• size – The number of bytes to send.
Returns
1 on success or 0 on failure.
Usage
This method can be used to send a large amount of data for a bound parameter in chunks.
Syntax
public size_t sqlany_sqlstate ( a_sqlany_connection *
sqlany_conn, char * buffer, size_t size)
Parameters
• sqlany_conn – A connection object returned from sqlany_new_connection().
• buffer – A buffer to be filled with the current 5-character SQLSTATE.
• size – The buffer size.
Programming 517
SAP Sybase IQ Database API for C/C++
Returns
The number of bytes copied into the buffer.
Usage
For more information on SQLSTATE error messages, see SQL Anywhere error messages
sorted by SQLSTATE.
a_sqlany_data_direction() enumeration
A data direction enumeration.
a_sqlany_data_type() enumeration
Specifies the data type being passed in or retrieved.
a_sqlany_native_type() enumeration
An enumeration of the native types of values as described by the server.
Programming 519
SAP Sybase IQ Database API for C/C++
SACAPI_ERROR_SIZE variable
Returns the minimal error buffer size.
Syntax
#define SACAPI_ERROR_SIZE
SQLANY_API_VERSION_1 variable
Defines to indicate the API versions.
Syntax
#define SQLANY_API_VERSION_1
SQLANY_API_VERSION_2 variable
Version 2 introduced the "_ex" functions and the ability to cancel requests.
Syntax
#define SQLANY_API_VERSION_2
SQLAnywhereInterface structure
The SQL Anywhere C API interface structure.
Syntax
typedef struct SQLAnywhereInterface
Remarks
Only one instance of this structure is required in your application environment. This structure
is initialized by the sqlany_initialize_interface method. It attempts to load the SQL Anywhere
C API DLL or shared object dynamically and looks up all the entry points of the DLL. The
fields in the SQLAnywhereInterface structure is populated to point to the corresponding
functions in the DLL.
dll_handle void *
DLL handle.
Syntax
public void * dll_handle;
initialized int
Flag to know if initialized or not.
Syntax
public int initialized;
sqlany_affected_rows void *
Pointer to sqlany_affected_rows() function.
Syntax
public void * sqlany_affected_rows;
sqlany_bind_param void *
Pointer to sqlany_bind_param() function.
Syntax
public void * sqlany_bind_param;
sqlany_cancel void *
Pointer to sqlany_cancel() function.
Syntax
public void * sqlany_cancel;
sqlany_clear_error void *
Pointer to sqlany_clear_error() function.
Syntax
public void * sqlany_clear_error;
Programming 521
SAP Sybase IQ Database API for C/C++
sqlany_client_version void *
Pointer to sqlany_client_version() function.
Syntax
public void * sqlany_client_version;
sqlany_client_version_ex void *
Pointer to sqlany_client_version_ex() function.
Syntax
public void * sqlany_client_version_ex;
sqlany_commit void *
Pointer to sqlany_commit() function.
Syntax
public void * sqlany_commit;
sqlany_connect void *
Pointer to sqlany_connect() function.
Syntax
public void * sqlany_connect;
sqlany_describe_bind_param void *
Pointer to sqlany_describe_bind_param() function.
Syntax
public void * sqlany_describe_bind_param;
sqlany_disconnect void *
Pointer to sqlany_disconnect() function.
Syntax
public void * sqlany_disconnect;
sqlany_error void *
Pointer to sqlany_error() function.
Syntax
public void * sqlany_error;
sqlany_execute void *
Pointer to sqlany_execute() function.
Syntax
public void * sqlany_execute;
sqlany_execute_direct void *
Pointer to sqlany_execute_direct() function.
Syntax
public void * sqlany_execute_direct;
sqlany_execute_immediate void *
Pointer to sqlany_execute_immediate() function.
Syntax
public void * sqlany_execute_immediate;
sqlany_fetch_absolute void *
Pointer to sqlany_fetch_absolute() function.
Syntax
public void * sqlany_fetch_absolute;
sqlany_fetch_next void *
Pointer to sqlany_fetch_next() function.
Syntax
public void * sqlany_fetch_next;
Programming 523
SAP Sybase IQ Database API for C/C++
sqlany_fini void *
Pointer to sqlany_fini() function.
Syntax
public void * sqlany_fini;
sqlany_fini_ex void *
Pointer to sqlany_fini_ex() function.
Syntax
public void * sqlany_fini_ex;
sqlany_free_connection void *
Pointer to sqlany_free_connection() function.
Syntax
public void * sqlany_free_connection;
sqlany_free_stmt void *
Pointer to sqlany_free_stmt() function.
Syntax
public void * sqlany_free_stmt;
sqlany_get_bind_param_info void *
Pointer to sqlany_get_bind_param_info() function.
Syntax
public void * sqlany_get_bind_param_info;
sqlany_get_column void *
Pointer to sqlany_get_column() function.
Syntax
public void * sqlany_get_column;
sqlany_get_column_info void *
Pointer to sqlany_get_column_info() function.
Syntax
public void * sqlany_get_column_info;
sqlany_get_data void *
Pointer to sqlany_get_data() function.
Syntax
public void * sqlany_get_data;
sqlany_get_data_info void *
Pointer to sqlany_get_data_info() function.
Syntax
public void * sqlany_get_data_info;
sqlany_get_next_result void *
Pointer to sqlany_get_next_result() function.
Syntax
public void * sqlany_get_next_result;
sqlany_init void *
Pointer to sqlany_init() function.
Syntax
public void * sqlany_init;
sqlany_init_ex void *
Pointer to sqlany_init_ex() function.
Syntax
public void * sqlany_init_ex;
Programming 525
SAP Sybase IQ Database API for C/C++
sqlany_make_connection void *
Pointer to sqlany_make_connection() function.
Syntax
public void * sqlany_make_connection;
sqlany_make_connection_ex void *
Pointer to sqlany_make_connection_ex() function.
Syntax
public void * sqlany_make_connection_ex;
sqlany_new_connection void *
Pointer to sqlany_new_connection() function.
Syntax
public void * sqlany_new_connection;
sqlany_new_connection_ex void *
Pointer to sqlany_new_connection_ex() function.
Syntax
public void * sqlany_new_connection_ex;
sqlany_num_cols void *
Pointer to sqlany_num_cols() function.
Syntax
public void * sqlany_num_cols;
sqlany_num_params void *
Pointer to sqlany_num_params() function.
Syntax
public void * sqlany_num_params;
sqlany_num_rows void *
Pointer to sqlany_num_rows() function.
Syntax
public void * sqlany_num_rows;
sqlany_prepare void *
Pointer to sqlany_prepare() function.
Syntax
public void * sqlany_prepare;
sqlany_reset void *
Pointer to sqlany_reset() function.
Syntax
public void * sqlany_reset;
sqlany_rollback void *
Pointer to sqlany_rollback() function.
Syntax
public void * sqlany_rollback;
sqlany_send_param_data void *
Pointer to sqlany_send_param_data() function.
Syntax
public void * sqlany_send_param_data;
sqlany_sqlstate void *
Pointer to sqlany_sqlstate() function.
Syntax
public void * sqlany_sqlstate;
Programming 527
SAP Sybase IQ Database API for C/C++
a_sqlany_bind_param structure
A bind parameter structure used to bind parameter and prepared statements.
Syntax
typedef struct a_sqlany_bind_param
Remarks
To view examples of the a_sqlany_bind_param structure in use, see any of the following
sample files in the sdk\dbcapi\examples directory of your SQL Anywhere installation.
• preparing_statements.cpp
• send_retrieve_full_blob.cpp
• send_retrieve_part_blob.cpp
direction a_sqlany_data_direction
The direction of the data. (input, output, input_output).
Syntax
public a_sqlany_data_direction direction;
name char *
Name of the bind parameter. This is only used by sqlany_describe_bind_param().
Syntax
public char * name;
value a_sqlany_data_value
The actual value of the data.
Syntax
public a_sqlany_data_value value;
a_sqlany_bind_param_info structure
Gets information about the currently bound parameters.
Syntax
typedef struct a_sqlany_bind_param_info
Remarks
sqlany_get_bind_param_info() can be used to populate this structure.
To view examples of the a_sqlany_bind_param_info structure in use, see any of the following
sample files in the sdk\dbcapi\examples directory of your SQL Anywhere installation.
• preparing_statements.cpp
• send_retrieve_full_blob.cpp
• send_retrieve_part_blob.cpp
direction a_sqlany_data_direction
The direction of the parameter.
Syntax
public a_sqlany_data_direction direction;
input_value a_sqlany_data_value
Information about the bound input value.
Syntax
public a_sqlany_data_value input_value;
name char *
A pointer to the name of the parameter.
Syntax
public char * name;
output_value a_sqlany_data_value
Information about the bound output value.
Syntax
public a_sqlany_data_value output_value;
a_sqlany_column_info structure
Returns column metadata information.
Syntax
typedef struct a_sqlany_column_info
Programming 529
SAP Sybase IQ Database API for C/C++
Remarks
sqlany_get_column_info() can be used to populate this structure.
To view an example of the a_sqlany_column_info structure in use, see the following sample
file in the sdk\dbcapi\examples directory of your SQL Anywhere installation.
• dbcapi_isql.cpp
max_size size_t
The maximum size a data value in this column can take.
Syntax
public size_t max_size;
name char *
The name of the column (null-terminated).
Syntax
public char * name;
Remarks
The string can be referenced as long as the result set object is not freed.
native_type a_sqlany_native_type
The native type of the column in the database.
Syntax
public a_sqlany_native_type native_type;
nullable sacapi_bool
Indicates whether a value in the column can be null.
Syntax
public sacapi_bool nullable;
Syntax
public unsigned short precision;
Syntax
public unsigned short scale;
type a_sqlany_data_type
The column data type.
Syntax
public a_sqlany_data_type type;
a_sqlany_data_info structure
Returns metadata information about a column value in a result set.
Syntax
typedef struct a_sqlany_data_info
Remarks
sqlany_get_data_info() can be used to populate this structure with information about what
was last retrieved by a fetch operation.
To view an example of the a_sqlany_data_info structure in use, see the following sample file in
the sdk\dbcapi\examples directory of your SQL Anywhere installation.
• send_retrieve_part_blob.cpp
data_size size_t
The total number of bytes available to be fetched.
Syntax
public size_t data_size;
Remarks
This field is only valid after a successful fetch operation.
is_null sacapi_bool
Indicates whether the last fetched data is NULL.
Syntax
public sacapi_bool is_null;
Programming 531
SAP Sybase IQ Database API for C/C++
Remarks
This field is only valid after a successful fetch operation.
type a_sqlany_data_type
The type of the data in the column.
Syntax
public a_sqlany_data_type type;
a_sqlany_data_value structure
Returns a description of the attributes of a data value.
Syntax
typedef struct a_sqlany_data_value
Remarks
To view examples of the a_sqlany_data_value structure in use, see any of the following sample
files in the sdk\dbcapi\examples directory of your SQL Anywhere installation.
• dbcapi_isql.cpp
• fetching_a_result_set.cpp
• send_retrieve_full_blob.cpp
• preparing_statements.cpp
buffer char *
A pointer to user supplied buffer of data.
Syntax
public char * buffer;
buffer_size size_t
The size of the buffer.
Syntax
public size_t buffer_size;
is_null sacapi_bool *
A pointer to indicate whether the last fetched data is NULL.
Syntax
public sacapi_bool * is_null;
length size_t *
A pointer to the number of valid bytes in the buffer. This value must be less than buffer_size.
Syntax
public size_t * length;
type a_sqlany_data_type
The type of the data.
Syntax
public a_sqlany_data_type type;
Programming 533
SAP Sybase IQ Database API for C/C++
DBD::SQLAnywhere
DBD::SQLAnywhere is a driver for the Database Independent Interface for Perl (DBI)
module written by Tim Bunce. Once you have installed the DBI module and
DBD::SQLAnywhere, you can access and change the information in SAP Sybase IQ
databases from Perl.
The DBD::SQLAnywhere driver is thread-safe when using Perl with ithreads.
Requirements
The DBD::SQLAnywhere interface requires the following components.
• Perl 5.6.0 or later. On Windows, ActivePerl 5.6.0 build 616 or later is required.
• DBI 1.34 or later.
• A C compiler. On Windows, only the Microsoft Visual C++ compiler is supported.
Prerequisites
• Make the iqdemo database.
• Install ActivePerl 5.6.0 or later. You can use the ActivePerl installer to install Perl and
configure your computer. You do not need to recompile Perl.
• Install Microsoft Visual Studio and configure your environment.
If you did not choose to configure your environment at install time, you must set your
PATH, LIB, and INCLUDE environment variables correctly before proceeding. Microsoft
provides a batch file for this purpose. For 32-bit builds, a batch file called
vcvars32.bat is included in the vc\bin subdirectory of the Visual Studio 2005 or
2008 installation. For 64-bit builds, look for a 64-bit version of this batch file such as
Programming 535
Perl DBI Support
vcvarsamd64.bat. Open a new system command prompt and run this batch file
before continuing.
For more information about configuring a 64-bit Visual C++ build environment, see http://
msdn.microsoft.com/en-us/library/x4d2c09s.aspx.
Task
Later versions of Perl may show instead a table similar to the following. In this case, the
information indicates that DBI version 1.58 is installed.
If DBI is not installed, you must install it. To do so, enter the following command at the
ppm prompt.
ppm install dbi
3. At a command prompt, change to the SDK\Perl subdirectory of your SAP Sybase IQ
installation.
4. Enter the following commands to build and test DBD::SQLAnywhere.
perl Makefile.PL
nmake
If for any reason you need to start over, you can run the command nmake clean to
remove any partially built targets.
5. To test DBD::SQLAnywhere, copy the sample database file to your SDK\Perl directory
and make the tests.
copy "%ALLUSERSPROFILE%\SybaseIQ\demo\iqdemo.db" .
iqsrv16 demo
nmake test
If the tests do not run, ensure that the bin32 or bin64 subdirectory of the SAP Sybase IQ
installation is in your path.
6. To complete the installation, run the following command at the same prompt.
nmake install
The DBI Perl module and the DBD::SQLAnywhere interface are now ready to use.
Prerequisites
You must have ActivePerl 5.6.0 build 616 or later and a C compiler installed.
Task
If for any reason you need to start over, you can use the command make clean to
remove any partially built targets.
4. Use the following command to test the DBI module.
make test
5. To complete the installation, run the following command at the same prompt.
make install
6. Make sure the environment is set up for SAP Sybase IQ.
Depending on which shell you are using, enter the appropriate command to source the SAP
Sybase IQ configuration script from the SAP Sybase IQ installation directory:
In this shell... Use this command...
sh, ksh, or bash . bin/sa_config.sh
Programming 537
Perl DBI Support
If for any reason you need to start over, you can use the command make clean to
remove any partially built targets.
9. To test DBD::SQLAnywhere, copy the sample database file to your sdk/perl directory
and make the tests.
cp samples-dir/demo.db .
iqsrv16 demo
make test
If the tests do not run, ensure that the bin32 or bin64 subdirectory of the SAP Sybase IQ
installation is in your path.
10. To complete the installation, run the following command at the same prompt.
make install
The DBI Perl module and the DBD::SQLAnywhere interface are ready for use.
Next
Optionally, you can delete the DBI source tree. It is no longer required.
In addition, it is highly recommended that you run Perl in strict mode. This statement, which
for example makes explicit variable definitions mandatory, is likely to greatly reduce the
chance that you will run into mysterious errors due to such common mistakes as typographical
errors.
#!/usr/local/bin/perl -w
#
use DBI;
use strict;
The DBI module automatically loads the DBD drivers, including DBD::SQLAnywhere, as
required.
Optionally, you can append the user name or password value to the data-source string instead
of supplying them as separate parameters. If you do so, supply a blank string for the
corresponding argument. For example, in the above script may be altered by replacing the
statement that opens the connections with these statements:
Programming 539
Perl DBI Support
$data_src .= ";UID=$uid";
$data_src .= ";PWD=$pwd";
my $dbh = DBI->connect($data_src, '', '', \%defaults)
or die "Cannot connect to $data_src: $DBI::errstr\n";
sub db_query {
my($sel, $dbh) = @_;
my($row, $sth) = undef;
$sth = $dbh->prepare($sel);
$sth->execute;
print "Fields: $sth->{NUM_OF_FIELDS}\n";
print "Params: $sth->{NUM_OF_PARAMS}\n\n";
print join("\t\t", @{$sth->{NAME}}), "\n\n";
while($row = $sth->fetchrow_arrayref) {
print join("\t\t", @$row), "\n";
}
$sth = undef;
}
__END__
Prepared statements are not dropped from the database server until the Perl statement handle is
destroyed. To destroy a statement handle, reuse the variable or set it to undef. Calling the finish
method does not drop the handle. In fact, the finish method should not be called, except when
you have decided not to finish reading a result set.
To detect handle leaks, the SAP Sybase IQ database server limits the number of cursors and
prepared statements permitted to a maximum of 50 per connection by default. The resource
governor automatically generates an error if these limits are exceeded. If you get this error,
check for undestroyed statement handles. Use prepare_cached sparingly, as the statement
handles are not destroyed.
If necessary, you can alter these limits by setting the max_cursor_count and
max_statement_count options.
sub db_query {
my($sel, $dbh) = @_;
my($row, $sth) = undef;
$sth = $dbh->prepare($sel);
$sth->execute;
do {
print "Fields: $sth->{NUM_OF_FIELDS}\n";
print "Params: $sth->{NUM_OF_PARAMS}\n\n";
Programming 541
Perl DBI Support
sub db_insert {
my($ins, $dbh) = @_;
my($sth) = undef;
my @rows = (
"801,Alex,Alt,5 Blue Ave,New York,NY,USA,
10012,5185553434,BXM",
"802,Zach,Zed,82 Fair St,New York,NY,USA,
10033,5185552234,Zap"
);
$sth = $dbh->prepare($ins);
my $row = undef;
foreach $row ( @rows ) {
Programming 543
Perl DBI Support
Python Support
The SAP Sybase IQ Python database interface, sqlanydb, is a data access API for the Python
language. This section describes how to use SAP Sybase IQ with Python.
sqlanydb
The SQL Anywhere Python database interface (sqlanydb) is a data access API for the Python
language. The Python Database API specification defines a set of methods that provides a
consistent database interface independent of the actual database being used. Using the
sqlanydb module, your Python scripts have direct access to SAP Sybase IQ database servers.
The sqlanydb module implements, with extensions, the Python Database API specification
v2.0 written by Marc-André Lemburg. Once you have installed the sqlanydb module, you can
access and change the information in SAP Sybase IQ databases from Python.
For information about the Python Database API specification v2.0, see http://
www.python.org/dev/peps/pep-0249/.
The sqlanydb module is thread-safe when using Python with threads.
Requirements
The sqlanydb module requires the following components.
• Python is required. For a list of supported versions, see http://www.sybase.com/detail?
id=1068981.
• The ctypes module is required. To test if the ctypes module is present, open a command
prompt window and run Python.
At the Python prompt, enter the following statement.
import ctypes
If you see an error message, then ctypes is not present. The following is an example.
>>> import ctypes
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ImportError: No module named ctypes
If ctypes is not included in your Python installation, install it. Installs can be found in the
SourceForge.net files section at http://sourceforge.net/project/showfiles.php?
group_id=71702.
Peak EasyInstall also installs ctypes. To download Peak EasyInstall, go to http://
peak.telecommunity.com/DevCenter/EasyInstall.
Programming 545
Python Support
Prerequisites
Ensure that Python and the ctypes module are installed. For a list of supported versions of
Python, see http://www.sybase.com/detail?id=1068981.
Task
The test script makes a connection to the database server and executes a SQL query. If
successful, the test displays the message sqlanydb successfully installed.
If the tests do not run, ensure that the bin32 or bin64 subdirectory of the SAP Sybase IQ
installation is in your path.
Prerequisites
Ensure that Python and the ctypes module are installed. For a list of supported versions of
Python, see http://www.sybase.com/detail?id=1068981.
Task
The test script makes a connection to the database server and executes a SQL query. If
successful, the test displays the message sqlanydb successfully installed.
If the test does not run, ensure that the bin32 or bin64 subdirectory of the SAP Sybase
IQ installation is in your path.
Programming 547
Python Support
To avoid starting the database server manually, you could use a data source that is configured
to start the server. This is shown in the following example.
import sqlanydb
Programming 549
Python Support
con.commit()
con.close()
Although both examples may appear to be equally suitable techniques for inserting row data
into a table, the latter example is superior for a couple of reasons. If the data values are
obtained by prompts for input, then the first example is susceptible to injection of rogue data
including SQL statements. In the first example, the execute method is called for each row to be
inserted into the table. In the second example, the executemany method is called only once to
insert all the rows into the table.
def convert_to_decimal(num):
return decimal.Decimal(num)
sqlanydb.register_converter(sqlanydb.DT_DECIMAL,
convert_to_decimal)
The following example demonstrates how to convert decimal results to integer resulting in the
truncation of any digits after the decimal point. The salary amount displayed when the
application is run is an integral value.
import sqlanydb
def convert_to_int(num):
return int(float(num))
sqlanydb.register_converter(sqlanydb.DT_DECIMAL, convert_to_int)
Programming 551
Python Support
PHP Support
PHP provides the ability to retrieve information from many popular databases. SAP Sybase IQ
includes a module that provides access to SAP Sybase IQ databases from PHP. You can use the
PHP language to retrieve information from SAP Sybase IQ databases and provide dynamic
web content on your own web sites.
Prerequisites
All of the required PHP components should be installed on your system
Programming 553
PHP Support
Task
1. Make sure that the bin32 subdirectory of your SAP Sybase IQ installation is in your path.
The SAP Sybase IQ PHP extension requires the bin32 directory to be in your path.
2. At a command prompt, run the following command to start the SAP Sybase IQ sample
database.
cd "%ALLUSERSPROFILE%"\SybaseIQ\demo
start_iq @iqdemo.cfg iqdemo.db
Messages similar to the following should appear. If the PHP command is not recognized,
verify that PHP is in your path.
Installation successful
Using php-5.2.11_sqlanywhere.dll
Connected successfully
If the SAP Sybase IQ PHP extension does not load, you can use the command "php -i" for
helpful information about your PHP setup. Search for extension_dir and
sqlanywhere in the output from this command.
4. When you are done, stop the SAP Sybase IQ database server by clicking Shut Down in the
database server messages window.
The tests should succeed, indicating that the SAP Sybase IQ PHP extension is working
correctly.
Prerequisites
You must install PHP. For information about installing PHP, see http://us2.php.net/install.
Task
This procedure applies to all configurations.
The PHP function, phpinfo, generates a page of system setup information. This confirms
that your installation of PHP and your web server are working together properly.
3. Copy the file connect.php from the sdk\php\examples directory to your root
web content directory. This confirms that your installation of PHP and SQL Anywhere are
working together properly.
4. Create a file in your root web content directory named sa_test.php and insert the
following code into this file:
<?php
$conn = sasql_connect( "UID=DBA;PWD=sql" );
$result = sasql_query( $conn, "SELECT * FROM Employees" );
sasql_result_all( $result );
sasql_free_result( $result );
sasql_disconnect( $conn );
?>
The info page displays the output from the phpinfo() call.
Programming 555
PHP Support
This script attempts to make a connection to a database on a local server. For this code to
succeed, the SAP Sybase IQ sample database or one with identical credentials must be started
on a local server.
<?php
# Connect using the default user ID and password
$conn = sasql_connect( "UID=DBA;PWD=sql" );
if( ! $conn ) {
echo "sasql_connect failed\n";
} else {
echo "Connected successfully\n";
# Execute a SELECT statement
$result = sasql_query( $conn, "SELECT * FROM Customers" );
if( ! $result ) {
echo "sasql_query failed!";
} else {
echo "query completed successfully\n";
# Generate HTML from the result set
sasql_result_all( $result );
sasql_free_result( $result );
}
sasql_close( $conn );
}
?>
The sasql_result_all function fetches all the rows of the result set and generates an HTML
output table to display them. The sasql_free_result function releases the resources used to
store the result set.
Programming 557
PHP Support
The sasql_fetch_array function returns a single row from the table. The data can be retrieved
by column names and column indexes.
The sasql_fetch_assoc function returns a single row from the table as an associative array. The
data can be retrieved by using the column names as indexes. The following is an example.
<?php
# Connect using the default user ID and password
$conn = sasql_connect("UID=DBA;PWD=sql");
/* check connection */
if( sasql_errorcode() ) {
printf("Connect failed: %s\n", sasql_error());
exit();
}
/* close connection */
sasql_close($conn);
?>
Two other similar methods are provided in the PHP interface: sasql_fetch_row returns a row
that can be searched by column indexes only, while sasql_fetch_object returns a row that can
be searched by column names only.
For an example of the sasql_fetch_object function, see the fetch_object.php example
script.
Programming 559
PHP Support
}
?>
In the above sample, the SQL statement selects the table ID and name for each table from
SYSTAB. The sasql_query function returns an array of rows. The script iterates through the
rows using the sasql_fetch_array function to retrieve the rows from an array. An inner iteration
goes through the columns of each row and prints their values.
Web Forms
PHP can take user input from a web form, pass it to the database server as a SQL query, and
display the result that is returned. The following example demonstrates a simple web form that
gives the user the ability to query the sample database using SQL statements and display the
results in an HTML table.
The source code for this sample is contained in your SAP Sybase IQ installation in a file called
webisql.php.
<?php
echo "<HTML>\n";
$qname = $_POST["qname"];
$qname = str_replace( "\\", "", $qname );
echo "<form method=post action=webisql.php>\n";
echo "<br>Query: <input type=text Size=80 name=qname value=\"$qname
\">\n";
echo "<input type=submit>\n";
echo "</form>\n";
echo "<HR><br>\n";
if( ! $qname ) {
echo "No Current Query\n";
return;
}
# Connect to the database
$con_str =
"UID=<user_id>;PWD=<password>;SERVER=iqdemo;LINKS=tcpip";
$conn = sasql_connect( $con_str );
if( ! $conn ) {
echo "sasql_connect failed\n";
echo "</html>\n";
return 0;
}
$qname = str_replace( "\\", "", $qname );
$result = sasql_query( $conn, $qname );
if( ! $result ) {
echo "sasql_query failed!";
} else {
// echo "query completed successfully\n";
sasql_result_all( $result, "border=1" );
sasql_free_result( $result );
}
sasql_disconnect( $conn );
echo "</html>\n";
?>
This design could be extended to handle complex web forms by formulating customized SQL
queries based on the values entered by the user.
To be able to send the binary data from the database directly to a web browser, the script must
set the data's MIME type using the header function. In this case, the browser is told to expect a
GIF image so it can display it correctly.
Programming 561
PHP Support
Adding the SAP Sybase IQ PHP Extension Files to the PHP Source Tree on
Unix
This topic describes the steps required to add the SAP Sybase IQ PHP extension files to the
PHP source tree.
Prerequisites
The following is a list of software you need to have on your system to complete to use the SAP
Sybase IQ PHP extension on Unix:
• an SAP Sybase IQ installation, which can run on the same computer as the Apache web
server, or on a different computer.
• The source code for the SQL Anywhere PHP extension, which can be downloaded from
http://download.sybase.com/ianywhere/php/2.0.3/src/sasql_php.zip.
You also need sqlpp and libdblib16.so (Unix) installed (check your SAP Sybase
IQ lib32 directory).
• The PHP source code, which can be downloaded from http://www.php.net.
For a list of supported versions, see http://www.sybase.com/detail?id=1068981.
• The Apache web server source code, which can be downloaded from http://
httpd.apache.org.
If you are going to use a pre-built version of Apache, make sure that you have apache and
apache-devel installed.
• If you plan to use the Unified ODBC PHP extension, you need to have
libdbodbc16.so (Unix) installed (check your SAP Sybase IQ lib32 directory).
The following binaries should be installed from your Unix installation disk if they are not
already installed, and can be found as RPMs:
make
automake
autoconf
makeinfo
bison
gcc
cpp
glibc-devel
kernel-headers
flex
You must have the same access privileges as the person who installed PHP to perform certain
steps of the installation. Most Unix-based systems offer a sudo command that allows users
with insufficient permissions to execute certain commands as a user with the right to execute
them.
Task
You must have the same access privileges as the person who installed PHP to perform certain
steps of the installation. Most Unix-based systems offer a sudo command that allows users
with insufficient permissions to execute certain commands as a user with the right to execute
them.
1. Download the SAP Sybase IQ PHP extension source code from http://www.sybase.com/
detail?id=1019698. Look for the section entitled Building the Driver from Source.
2. From the directory where you saved the SAP Sybase IQ PHP extension, extract the files to
the ext subdirectory of the PHP source tree:
$ tar -xzf sasql_php.zip -C PHP-source-directory/ext/
The following example is for PHP version 5.2.11. You must change php-5.2.11 below to
the version of PHP you are using.
$ tar -xzf sqlanywhere_php-1.0.8.tar.gz -C ~/php-5.2.11/ext
3. Make PHP aware of the extension:
$ cd PHP-source-directory/ext/sqlanywhere
$ touch *
$ cd ~/PHP-source-directory
$ ./buildconf
The following example is for PHP version 5.2.11. You must change php-5.2.11 below to
the version of PHP you are using.
$ cd ~/php-5.2.11/ext/sqlanywhere
$ touch *
$ cd ~/php-5.2.11
$ ./buildconf
4. Verify that PHP is aware of the extension:
$ ./configure -help | egrep sqlanywhere
If you were successful in making PHP aware of the SAP Sybase IQ extension, you should see
the following text:
--with-sqlanywhere=[DIR]
If you are unsuccessful, keep track of the output of this command and post it to the SQL
Anywhere Forum at http://sqlanywhere-forum.sybase.com/ for assistance.
Programming 563
PHP Support
Prerequisites
Configure Apache so that it recognizes shared modules using the following steps.
• Configure Apache to recognize shared modules.
Execute commands similar to the following from the directory where your Apache files
were extracted:
$ cd Apache-source-directory
$ ./configure --enabled-shared=max --enable-module=most --
prefix=/Apache-installation-directory
The following example is for Apache version 2.2.9. You must change apache_2.2.9 to
the version of Apache you are using.
$ cd ~/apache_2.2.9
$ ./configure --enabled-shared=max --enable-module=most --
prefix=/usr/local/web/apache
• Recompile and install the relevant components:
$ make
$ make install
Task
1. Make sure the environment is set up for SAP Sybase IQ.
Depending on which shell you are using, enter the appropriate command from the
directory where SAP Sybase IQ is installed.
If you are using this shell... ...use this command
sh, ksh, bash ../IQ_16.sh
2. Configure PHP as an Apache module to include the SAP Sybase IQ PHP extension.
Run the following commands:
$ cd PHP-source-directory
$ ./configure --with-sqlanywhere --with- apxs=/Apache-
installation-directory/bin/apxs
The following example is for PHP version 5.2.11. You must change php-5.2.11 to the
version of PHP you are using.
$ cd ~/php-5.2.11
The configure script will try to determine the version and location of your SAP Sybase
IQ installation.
3. Recompile the relevant components:
$ make
4. Check that the libraries are properly linked.
• Linux users (the following example assumes you are using PHP version 5):
ldd ./.libs/libphp5.so
5. Install the PHP binaries in Apache's lib directory:
$ make install
6. Perform verification. PHP does this automatically. All you need is to make sure that your
httpd.conf configuration file is verified so that Apache will recognize .php files as
PHP scripts.
httpd.conf is stored in the conf subdirectory of the Apache directory:
$ cd Apache-installation-directory/conf
For example:
$ cd /usr/local/web/apache/conf
Make a backup copy of httpd.conf before editing the file (you can replace pico with
the text editor of your choice):
$ cp httpd.conf httpd.conf.backup
$ pico httpd.conf
Add or uncomment the following lines in httpd.conf (they are not located together in
the file):
LoadModule php5_module libexec/libphp5.so
AddModule mod_php5.c
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
The first two lines point Apache to the files that are used for interpreting PHP code, while
the other two lines declare file types for files whose extension is .php or .phps so
Apache can recognize and deal with them appropriately.
PHP is successfully compiled as a shared module.
Prerequisites
There are no prerequisites for this task.
Programming 565
PHP Support
Task
2. Configure PHP as a CGI executable and with the SAP Sybase IQ PHP extension.
Run the following command from the directory where your PHP files were extracted:
$ cd PHP-source-directory
$ ./configure --with-sqlanywhere
The following example is for PHP version 5.2.11. You must change php-5.2.11 to the
version of PHP you are using.
$ cd ~/php-5.2.11
$ ./configure --with-sqlanywhere
The configuration script will try to determine the version and location of your SAP Sybase
IQ installation.
3. Compile the executable:
$ make
4. Install the components.
$ make install
sasql_affected_rows
Returns the number of rows affected by the last SQL statement. This function is typically used
for INSERT, UPDATE, or DELETE statements. For SELECT statements, use the
sasql_num_rows function.
Prototype
int sasql_affected_rows( sasql_conn $conn )
Parameters
$conn – The connection resource returned by a connect function.
Returns
The number of rows affected.
sasql_commit
Ends a transaction on the SQL Anywhere database and makes any changes made during the
transaction permanent. Useful only when the auto_commit option is Off
Prototype
bool sasql_commit( sasql_conn $conn )
Parameters
$conn – The connection resource returned by a connect function.
Returns
TRUE on success or FALSE on failure.
sasql_close
Closes a previously opened database connection.
Prototype
bool sasql_close( sasql_conn $conn )
Parameters
$conn – The connection resource returned by a connect function.
Returns
TRUE on success or FALSE on failure.
sasql_connect
Establishes a connection to an SAP Sybase IQ database.
Prototype
sasql_conn sasql_connect( string $con_str )
Parameters
$con_str – A connection string as recognized by SAP Sybase IQ.
Programming 567
PHP Support
Returns
A positive SAP Sybase IQ connection resource on success, or an error and 0 on failure.
sasql_data_seek
Positions the cursor on row row_num on the $result that was opened using sasql_query.
Prototype
bool sasql_data_seek( sasql_result $result, int row_num )
Parameters
$result – The result resource returned by the sasql_query function.
row_num – An integer that represents the new position of the cursor within the result
resource. For example, specify 0 to move the cursor to the first row of the result set or 5 to move
it to the sixth row. Negative numbers represent rows relative to the end of the result set. For
example, -1 moves the cursor to the last row in the result set and -2 moves it to the second-last
row.
Returns
TRUE on success or FALSE on error.
sasql_disconnect
Closes a connection that has been opened with sasql_connect or sasql_pconnect.
Prototype
bool sasql_disconnect( sasql_conn $conn )
Parameters
$conn – The connection resource returned by a connect function.
Returns
TRUE on success or FALSE on error.
sasql_error
Returns the error text of the most recently executed SAP Sybase IQ PHP function. Error
messages are stored per connection. If no $conn is specified, then sasql_error returns the last
error message where no connection was available. For example, if you call sasql_connect and
the connection fails, then call sasql_error with no parameter for $conn to get the error
message. To obtain the corresponding error code value, use the sasql_errorcode function.
Prototype
string sasql_error( [ sasql_conn $conn ] )
Parameters
$conn – The connection resource returned by a connect function.
Returns
A string describing the error.
sasql_errorcode
Returns the error code of the most-recently executed SAP Sybase IQ PHP function. Error
codes are stored per connection. If no $conn is specified, then sasql_errorcode returns the last
error code where no connection was available. For example, if you are calling sasql_connect
and the connection fails, then call sasql_errorcode with no parameter for the $conn to get the
error code. To get the corresponding error message use the sasql_error function
Prototype
int sasql_errorcode( [ sasql_conn $conn ] )
Parameters
$conn – The connection resource returned by a connect function.
Returns
An integer representing an error code. An error code of 0 means success. A positive error code
indicates success with warnings. A negative error code indicates failure.
sasql_escape_string
Escapes all special characters in the supplied string. The special characters that are escaped are
\r, \n, ', ", ;, \, and the NULL character. This function is an alias of sasql_real_escape_string.
Prototype
string sasql_escape_string( sasql_conn $conn, string $str )
Parameters
$conn – The connection resource returned by a connect function.
$string – The string to be escaped.
Returns
The escaped string.
Programming 569
PHP Support
sasql_fetch_array
Fetches one row from the result set. This row is returned as an array that can be indexed by the
column names or by the column indexes.
Prototype
array sasql_fetch_array( sasql_result $result [, int
$result_type ])
Parameters
$result – The result resource returned by the sasql_query function.
$result_type – This optional parameter is a constant indicating what type of array should be
produced from the current row data. The possible values for this parameter are the constants
SASQL_ASSOC, SASQL_NUM, or SASQL_BOTH. It defaults to SASQL_BOTH.
By using the SASQL_ASSOC constant this function will behave identically to the
sasql_fetch_assoc function, while SASQL_NUM will behave identically to the
sasql_fetch_row function. The final option SASQL_BOTH will create a single array with the
attributes of both.
Returns
An array that represents a row from the result set, or FALSE when no rows are available.
sasql_fetch_assoc
Fetches one row from the result set as an associative array.
Prototype
array sasql_fetch_assoc( sasql_result $result )
Parameters
$result – The result resource returned by the sasql_query function.
Returns
An associative array of strings representing the fetched row in the result set, where each key in
the array represents the name of one of the result set's columns or FALSE if there are no more
rows in resultset.
sasql_fetch_field
Returns an object that contains information about a specific column.
Prototype
object sasql_fetch_field( sasql_result $result [, int
$field_offset ] )
Parameters
$result – The result resource returned by the sasql_query function.
$field_offset – An integer representing the column/field on which you want to retrieve
information. Columns are zero based; to get the first column, specify the value 0. If this
parameter is omitted, then the next field object is returned.
Returns
An object that has the following properties:
• id – contains the field's number.
• name – contains the field's name.
• numeric – indicates whether the field is a numeric value.
• length – returns the field's native storage size.
• type – returns the field's type.
• native_type – returns the field's native type. These are values like DT_FIXCHAR,
DT_DECIMAL or DT_DATE.
• precision – returns the field's numeric precision. This property is only set for fields with
native_type equal to DT_DECIMAL.
• scale – returns the field's numeric scale. This property is only set for fields with
native_type equal to DT_DECIMAL.
sasql_fetch_object
Fetches one row from the result set as an object.
Prototype
object sasql_fetch_object( sasql_result $result )
Parameters
$result – The result resource returned by the sasql_query function.
Returns
An object representing the fetched row in the result set where each property name matches one
of the result set column names, or FALSE if there are no more rows in result set.
Programming 571
PHP Support
sasql_fetch_row
Fetches one row from the result set. This row is returned as an array that can be indexed by the
column indexes only.
Prototype
array sasql_fetch_row( sasql_result $result )
Parameters
$result – The result resource returned by the sasql_query function.
Returns
An array that represents a row from the result set, or FALSE when no rows are available.
sasql_field_count
Returns the number of columns (fields) the last result contains.
Prototype
int sasql_field_count( sasql_conn $conn )
Parameters
$conn – The connection resource returned by a connect function.
Returns
A positive number of columns, or FALSE if $conn is not valid.
sasql_field_seek
Sets the field cursor to the given offset. The next call to sasql_fetch_field will retrieve the field
definition of the column associated with that offset.
Prototype
bool sasql_field_seek( sasql_result $result, int $field_offset )
Parameters
$result – The result resource returned by the sasql_query function.
$field_offset – An integer representing the column/field on which you want to retrieve
information. Columns are zero based; to get the first column, specify the value 0. If this
parameter is omitted, then the next field object is returned.
Returns
TRUE on success or FALSE on error.
sasql_free_result
Frees database resources associated with a result resource returned from sasql_query.
Prototype
bool sasql_free_result( sasql_result $result )
Parameters
$result – The result resource returned by the sasql_query function.
Returns
TRUE on success or FALSE on error.
sasql_get_client_info
Returns the version information of the client.
Prototype
string sasql_get_client_info( )
Parameters
None
Returns
A string that represents the SQL Anywhere client software version. The returned string is of
the form X.Y.Z.W where X is the major version number, Y is the minor version number, Z is
the patch number, and W is the build number (for example, 10.0.1.3616).
sasql_insert_id
Returns the last value inserted into an IDENTITY column or a DEFAULT
AUTOINCREMENT column, or zero if the most recent insert was into a table that did not
contain an IDENTITY or DEFAULT AUTOINCREMENT column. The sasql_insert_id
function is provided for compatibility with MySQL databases.
Prototype
int sasql_insert_id( sasql_conn $conn )
Parameters
$conn – The connection resource returned by a connect function.
Programming 573
PHP Support
Returns
The ID generated for an AUTOINCREMENT column by a previous INSERT statement or
zero if last insert did not affect an AUTOINCREMENT column. The function can return
FALSE if the $conn is not valid.
sasql_message
Writes a message to the server messages window.
Prototype
bool sasql_message( sasql_conn $conn, string $message )
Parameters
$conn – The connection resource returned by a connect function.
$message – A message to be written to the server messages window.
Returns
TRUE on success or FALSE on failure.
sasql_multi_query
Prepares and executes one or more SQL queries specified by $sql_str using the supplied
connection resource. Each query is separated from the other using semicolons. The first query
result can be retrieved or stored using sasql_use_result or sasql_store_result.
sasql_field_count can be used to check if the query returns a result set or not. All subsequent
query results can be processed using sasql_next_result and sasql_use_result/
sasql_store_result.
Prototype
bool sasql_multi_query( sasql_conn $conn, string $sql_str )
Parameters
$conn – The connection resource returned by a connect function.
$sql_str – One or more SQL statements separated by semicolons.
Returns
TRUE on success or FALSE on failure.
sasql_next_result
Prepares the next result set from the last query that executed on $conn.
Prototype
bool sasql_next_result( sasql_conn $conn )
Parameters
$conn – The connection resource returned by a connect function.
Returns
FALSE if there is no other result set to be retrieved. TRUE if there is another result to be
retrieved. Call sasql_use_result or sasql_store_result to retrieve the next result set.
sasql_num_fields
Returns the number of fields that a row in the $result contains.
Prototype
int sasql_num_fields( sasql_result $result )
Parameters
$result – The result resource returned by the sasql_query function.
Returns
Returns the number of fields in the specified result set.
sasql_num_rows
Returns the number of rows that the $result contains.
Prototype
int sasql_num_rows( sasql_result $result )
Parameters
$result – The result resource returned by the sasql_query function.
Returns
A positive number if the number of rows is exact, or a negative number if it is an estimate. To
get the exact number of rows, the database option row_counts must be set permanently on the
database, or temporarily on the connection.
Programming 575
PHP Support
sasql_pconnect
Establishes a persistent connection to an SAP Sybase IQ database. Because of the way Apache
creates child processes, you may observe a performance gain when using sasql_pconnect
instead of sasql_connect. Persistent connections may provide improved performance in a
similar fashion to connection pooling. If your database server has a limited number of
connections (for example, the personal database server is limited to 10 concurrent
connections), caution should be exercised when using persistent connections. Persistent
connections could be attached to each of the child processes, and if you have more child
processes in Apache than there are available connections, you will receive connection errors.
Prototype
sasql_conn sasql_pconnect( string $con_str )
Parameters
$con_str – A connection string as recognized by SAP Sybase IQ.
Returns
A positive SAP Sybase IQ persistent connection resource on success, or an error and 0 on
failure.
sasql_prepare
Prepares the supplied SQL string.
Prototype
sasql_stmt sasql_prepare( sasql_conn $conn, string $sql_str )
Parameters
$conn – The connection resource returned by a connect function.
$sql_str – The SQL statement to be prepared. The string can include parameter markers by
embedding question marks at the appropriate positions.
Returns
A statement object or FALSE on failure.
sasql_query
Prepares and executes the SQL query $sql_str on the connection identified by $conn that has
already been opened using sasql_connect or sasql_pconnect. The sasql_query function is
Prototype
mixed sasql_query( sasql_conn $conn, string $sql_str [, int
$result_mode ] )
Parameters
$conn – The connection resource returned by a connect function.
$sql_str – A SQL statement supported by SQL Anywhere.
$result_mode – Either SASQL_USE_RESULT, or SASQL_STORE_RESULT (the default).
Returns
FALSE on failure; TRUE on success for INSERT, UPDATE, DELETE, CREATE;
sasql_result for SELECT.
sasql_real_escape_string
Escapes all special characters in the supplied string. The special characters that are escaped are
\r, \n, ', ", ;, \, and the NULL character.
Prototype
string sasql_real_escape_string( sasql_conn $conn, string $str )
Parameters
$conn – The connection resource returned by a connect function.
$string – The string to be escaped.
Returns
The escaped string or FALSE on error.
sasql_real_query
Executes a query against the database using the supplied connection resource. The query
result can be retrieved or stored using sasql_store_result or sasql_use_result. The
sasql_field_count function can be used to check if the query returns a result set or not. The
sasql_query function is equivalent to calling this function and one of sasql_store_result or
sasql_use_result.
Prototype
bool sasql_real_query( sasql_conn $conn, string $sql_str )
Programming 577
PHP Support
Parameters
$conn – The connection resource returned by a connect function.
$sql_str – A SQL statement supported by SQL Anywhere.
Returns
TRUE on success or FALSE on failure.
sasql_result_all
Fetches all results of the $result and generates an HTML output table with an optional
formatting string.
Prototype
bool sasql_result_all( resource $result
[, $html_table_format_string
[, $html_table_header_format_string
[, $html_table_row_format_string
[, $html_table_cell_format_string
] ] ] ] )
Parameters
$result – The result resource returned by the sasql_query function.
$html_table_format_string – A format string that applies to HTML tables. For example,
"Border=1; Cellpadding=5". The special value none does not create an HTML table.
This is useful to customize your column names or scripts. To avoid specifying an explicit value
for this parameter, use NULL for the parameter value.
$html_table_header_format_string – A format string that applies to column headings for
HTML tables. For example, "bgcolor=#FF9533". The special value none does not create
an HTML table. This is useful to customize your column names or scripts. To avoid specifying
an explicit value for this parameter, use NULL for the parameter value.
$html_table_row_format_string – A format string that applies to rows within HTML tables.
For example, "onclick='alert('this')'". If you would like different formats that
alternate, use the special token ><. The left side of the token indicates which format to use on
odd rows and the right side of the token is used to format even rows. If you do not place this
token in your format string, all rows have the same format. If you do not want to specify an
explicit value for this parameter, use NULL for the parameter value.
$html_table_cell_format_string – A format string that applies to cells within HTML table
rows. For example, "onclick='alert('this')'". If you do not want to specify an
explicit value for this parameter, use NULL for the parameter value.
Returns
TRUE on success or FALSE on failure.
sasql_rollback
Ends a transaction on the database and discards any changes made during the transaction. This
function is only useful when the auto_commit option is Off.
Prototype
bool sasql_rollback( sasql_conn $conn )
Parameters
$conn – The connection resource returned by a connect function.
Returns
TRUE on success or FALSE on failure.
sasql_set_option
Sets the value of the specified option on the specified connection.
Prototype
bool sasql_set_option( sasql_conn $conn, string $option, mixed
$value )
Description
You can set the value for the following options:
Name Description Default
auto_commit When this option is set to on, the on
database server commits after
executing each statement.
Programming 579
PHP Support
You can change the default value for an option by including the following line in the
php.ini file. In this example, the default value is set for the auto_commit option.
sqlanywhere.auto_commit=0
Parameters
$conn – The connection resource returned by a connect function.
$option – The name of the option you want to set.
$value – The new option value.
Returns
TRUE on success or FALSE on failure.
sasql_stmt_affected_rows
Returns the number of rows affected by executing the statement.
Prototype
int sasql_stmt_affected_rows( sasql_stmt $stmt )
Parameters
$stmt – A statement resource that was executed by sasql_stmt_execute.
Returns
The number of rows affected or FALSE on failure.
sasql_stmt_bind_param
Binds PHP variables to statement parameters.
Prototype
bool sasql_stmt_bind_param( sasql_stmt $stmt, string $types,
mixed &$var_1 [, mixed &$var_2 .. ] )
Parameters
$stmt – A prepared statement resource that was returned by the sasql_prepare function.
$types – A string that contains one or more characters specifying the types of the
corresponding bind. This can be any of: s for string, i for integer, d for double, b for blobs.
The length of the $types string must match the number of parameters that follow the $types
parameter ($var_1, $var_2, ...). The number of characters should also match the number of
parameter markers (question marks) in the prepared statement.
$var_n – The variable references.
Returns
TRUE if binding the variables was successful or FALSE otherwise.
sasql_stmt_bind_param_ex
Binds a PHP variable to a statement parameter.
Prototype
bool sasql_stmt_bind_param_ex( sasql_stmt $stmt, int
$param_number, mixed &$var, string $type [, bool $is_null [, int
$direction ] ] )
Parameters
$stmt – A prepared statement resource that was returned by the sasql_prepare function.
$param_number – The parameter number. This should be a number between 0 and
(sasql_stmt_param_count($stmt) - 1).
$var – A PHP variable. Only references to PHP variables are allowed.
$type – Type of the variable. This can be one of: s for string, i for integer, d for double, b for
blobs.
$is_null – Whether the value of the variable is NULL or not.
$direction – Can be SASQL_D_INPUT, SASQL_D_OUTPUT, or
SASQL_INPUT_OUTPUT.
Returns
TRUE if binding the variable was successful or FALSE otherwise.
Programming 581
PHP Support
sasql_stmt_bind_result
Binds one or more PHP variables to result columns of a statement that was executed, and
returns a result set.
Prototype
bool sasql_stmt_bind_result( sasql_stmt $stmt, mixed &$var1 [,
mixed &$var2 .. ] )
Parameters
$stmt – A statement resource that was executed by sasql_stmt_execute.
$var1 – References to PHP variables that will be bound to result set columns returned by the
sasql_stmt_fetch.
Returns
TRUE on success or FALSE on failure.
sasql_stmt_close
Closes the supplied statement resource and frees any resources associated with it. This
function will also free any result objects that were returned by the
sasql_stmt_result_metadata.
Prototype
bool sasql_stmt_close( sasql_stmt $stmt )
Parameters
$stmt – A prepared statement resource that was returned by the sasql_prepare function.
Returns
TRUE for success or FALSE on failure.
sasql_stmt_data_seek
This function seeks to the specified offset in the result set.
Prototype
bool sasql_stmt_data_seek( sasql_stmt $stmt, int $offset )
Parameters
$stmt – A statement resource.
$offset – The offset in the result set. This is a number between 0 and
(sasql_stmt_num_rows($stmt) - 1).
Returns
TRUE on success or FALSE failure.
sasql_stmt_errno
Returns the error code for the most recently executed statement function using the specified
statement resource.
Prototype
int sasql_stmt_errno( sasql_stmt $stmt )
Parameters
$stmt – A prepared statement resource that was returned by the sasql_prepare function.
Returns
An integer error code.
sasql_stmt_error
Returns the error text for the most recently executed statement function using the specified
statement resource.
Prototype
string sasql_stmt_error( sasql_stmt $stmt )
Parameters
$stmt – A prepared statement resource that was returned by the sasql_prepare function.
Returns
A string describing the error.
sasql_stmt_execute
Executes the prepared statement. The sasql_stmt_result_metadata can be used to check
whether the statement returns a result set.
Prototype
bool sasql_stmt_execute( sasql_stmt $stmt )
Programming 583
PHP Support
Parameters
$stmt – A prepared statement resource that was returned by the sasql_prepare function.
Variables should be bound before calling execute.
Returns
TRUE for success or FALSE on failure.
sasql_stmt_fetch
This function fetches one row out of the result for the statement and places the columns in the
variables that were bound using sasql_stmt_bind_result.
Prototype
bool sasql_stmt_fetch( sasql_stmt $stmt )
Parameters
$stmt – A statement resource.
Returns
TRUE on success or FALSE on failure.
sasql_stmt_field_count
This function returns the number of columns in the result set of the statement.
Prototype
int sasql_stmt_field_count( sasql_stmt $stmt )
Parameters
$stmt – A statement resource.
Returns
The number of columns in the result of the statement. If the statement does not return a result,
it returns 0.
sasql_stmt_free_result
This function frees cached result set of the statement.
Prototype
bool sasql_stmt_free_result( sasql_stmt $stmt )
Parameters
$stmt – A statement resource that was executed using sasql_stmt_execute.
Returns
TRUE on success or FALSE on failure.
sasql_stmt_insert_id
Returns the last value inserted into an IDENTITY column or a DEFAULT
AUTOINCREMENT column, or zero if the most recent insert was into a table that did not
contain an IDENTITY or DEFAULT AUTOINCREMENT column.
Prototype
int sasql_stmt_insert_id( sasql_stmt $stmt )
Parameters
$stmt – A statement resource that was executed by sasql_stmt_execute.
Returns
The ID generated for an IDENTITY column or a DEFAULT AUTOINCREMENT column by
a previous INSERT statement, or zero if the last insert did not affect an IDENTITY or
DEFAULT AUTOINCREMENT column. The function can return FALSE (0) if $stmt is not
valid.
sasql_stmt_next_result
This function advances to the next result from the statement. If there is another result set, the
currently cashed results are discarded and the associated result set object deleted (as returned
by sasql_stmt_result_metadata).
Prototype
bool sasql_stmt_next_result( sasql_stmt $stmt )
Parameters
$stmt – A statement resource.
Returns
TRUE on success or FALSE failure.
Programming 585
PHP Support
sasql_stmt_num_rows
Returns the number of rows in the result set. The actual number of rows in the result set can
only be determined after the sasql_stmt_store_result function is called to buffer the entire
result set. If the sasql_stmt_store_result function has not been called, 0 is returned.
Prototype
int sasql_stmt_num_rows( sasql_stmt $stmt )
Parameters
$stmt – A statement resource that was executed by sasql_stmt_execute and for which
sasql_stmt_store_result was called.
Returns
The number of rows available in the result or 0 on failure.
sasql_stmt_param_count
Returns the number of parameters in the supplied prepared statement resource.
Prototype
int sasql_stmt_param_count( sasql_stmt $stmt )
Parameters
$stmt – A statement resource returned by the sasql_prepare function.
Returns
The number of parameters or FALSE on error.
sasql_stmt_reset
This function resets the $stmt object to the state just after the describe. Any variables that were
bound are unbound and any data sent using sasql_stmt_send_long_data are dropped.
Prototype
bool sasql_stmt_reset( sasql_stmt $stmt )
Parameters
$stmt – A statement resource.
Returns
TRUE on success or FALSE on failure.
sasql_stmt_result_metadata
Returns a result set object for the supplied statement.
Prototype
sasql_result sasql_stmt_result_metadata( sasql_stmt $stmt )
Parameters
$stmt – A statement resource that was prepared and executed.
Returns
sasql_result object or FALSE if the statement does not return any results.
sasql_stmt_send_long_data
Allows the user to send parameter data in chunks. The user must first call
sasql_stmt_bind_param or sasql_stmt_bind_param_ex before attempting to send any data.
The bind parameter must be of type string or blob. Repeatedly calling this function appends on
to what was previously sent.
Prototype
bool sasql_stmt_send_long_data( sasql_stmt $stmt, int
$param_number, string $data )
Parameters
$stmt – A statement resource that was prepared using sasql_prepare.
$param_number – The parameter number. This must be a number between 0 and
(sasql_stmt_param_count($stmt) - 1).
$data – The data to be sent.
Returns
TRUE on success or FALSE on failure.
sasql_stmt_store_result
This function allows the client to cache the whole result set of the statement. You can use the
function sasql_stmt_free_result to free the cached result.
Prototype
bool sasql_stmt_store_result( sasql_stmt $stmt )
Programming 587
PHP Support
Parameters
$stmt – A statement resource that was executed using sasql_stmt_execute.
Returns
TRUE on success or FALSE on failure.
sasql_store_result
Transfers the result set from the last query on the database connection $conn to be used with
the sasql_data_seek function.
Prototype
sasql_result sasql_store_result( sasql_conn $conn )
Parameters
$conn – The connection resource returned by a connect function.
Returns
FALSE if the query does not return a result object, or a result set object, that contains all the
rows of the result. The result is cached at the client.
sasql_sqlstate
Returns the most recent SQLSTATE string. SQLSTATE indicates whether the most recently
executed SQL statement resulted in a success, error, or warning condition. SQLSTATE codes
consists of five characters with "00000" representing no error. The values are defined by the
ISO/ANSI SQL standard.
Prototype
string sasql_sqlstate( sasql_conn $conn )
Parameters
$conn – The connection resource returned by a connect function.
Returns
Returns a string of five characters containing the current SQLSTATE code. The result "00000"
means no error.
sasql_use_result
Initiates a result set retrieval for the last query that executed on the connection.
Prototype
sasql_result sasql_use_result( sasql_conn $conn )
Parameters
$conn – The connection resource returned by a connect function.
Returns
FALSE if the query does not return a result object or a result set object. The result is not cached
on the client.
Programming 589
PHP Support
Ruby Support
There are three different Ruby Application Programming Interfaces supported by SAP Sybase
IQ. First, there is the SAP Sybase IQ Ruby API. This API provides a Ruby wrapping over the
interface exposed by the SAP Sybase IQ C API. Second, there is support for ActiveRecord, an
object-relational mapper popularized by being part of the Ruby on Rails web development
framework. Third, there is support for Ruby DBI. SAP Sybase IQ provides a Ruby Database
Driver (DBD) which can be used with DBI.
This package is a prerequisite for any of the other SQL Anywhere Ruby packages.
Rails
Rails is a web development framework written in the Ruby language. Its strength is in web
application development. A familiarity with the Ruby programming language is highly
recommended before you attempt Rails development. See http://www.rubyonrails.org/.
ActiveRecord Adapter
activerecord-sqlanywhere-adapter – This package is an adapter that allows ActiveRecord
to communicate with SAP Sybase IQ. ActiveRecord is an object-relational mapper,
popularized by being part of the Ruby on Rails web development framework. This package is
written in pure Ruby, and available in source, or gem format. This adapter uses (and has a
dependency on) the sqlanywhere gem. If you have RubyGems installed, this package and
its dependencies can be installed by running the following command:
gem install activerecord-sqlanywhere-adapter
Programming 591
Ruby Support
dbd-sqlanywhere – This package is a driver that allows Ruby/DBI to communicate with SAP
Sybase IQ. Ruby/DBI is a generic database interface modeled after the popular Perl DBI
module. This package is written in pure Ruby, and available in source, or gem format. This
driver uses (and has a dependency on) the sqlanywhere gem. If you have RubyGems installed,
this package and its dependencies can be installed by running the following command:
gem install dbd-sqlanywhere
For feedback on any of these packages, use the mailing list sqlanywhere-
[email protected].
Prerequisites
There are no prerequisites for this task.
Task
1. Install RubyGems. It simplifies the installation of Ruby packages. The Ruby on Rails
download page directs you to the correct version to install. See http://
www.rubyonrails.org/.
2. Install the Ruby interpreter on your system. The Ruby on Rails download page
recommends which version to install. See http://www.rubyonrails.org/.
3. Install Ruby Rails and its dependencies by running the following command:
gem install rails
4. Install the Ruby Development Kit (DevKit). Download the DevKit from http://
rubyinstaller.org/downloads/ and follow the instructions at http://github.com/oneclick/
rubyinstaller/wiki/Development-Kit.
5. Install the SQL Anywhere ActiveRecord support (activerecord-sqlanywhere-adapter) by
running the following command:
gem install activerecord-sqlanywhere-adapter
6. Add SAP Sybase IQ to the set of database management systems supported by Rails. At the
time of writing, Rails 3.1.3 was the current released version.
a. Configure a database by creating a sqlanywhere.yml file in the Rails configs
\databases directory. If you have installed Ruby in the \Ruby directory and you
have installed version 3.1.3 of Rails, then the path to this file would be \Ruby\lib
\ruby\gems\1.9.1\gems\railties-3.1.3\lib\rails
\generators\rails\app\templates\config\databases. The
contents of this file should be:
#
# SQL Anywhere database configuration
#
# This configuration file defines the patten used for
# database filenames. If your application is called "blog",
# then the database names will be blog_development,
# blog_test, blog_production. The specified username and
# password should permit DBA access to the database.
#
development:
adapter: sqlanywhere
server: <%= app_name %>
database: <%= app_name %>_development
username: DBA
password: sql
production:
adapter: sqlanywhere
server: <%= app_name %>
database: <%= app_name %>_production
username: DBA
password: sql
Programming 593
Ruby Support
Next
Start the database server and the three databases as follows.
iqsrv16 -n blog blog_development.db blog_production.db blog_test.db
The database server name in the command line (blog) must match the name specified by the
server: tags in the database.yml file. The sqlanywhere.yml template file is
configured to ensure that the database server name matches the project name in all generated
database.yml files.
Ruby-DBI Driver
This section provides an overview of how to write Ruby applications that use the DBI driver.
The DBI module automatically loads the SQLAnywhere database driver (DBD) interface as
required.
• server-name – is the name of the database server that you want to connect to. Alternately,
you can specify a connection string in the format "option1=value1;option2=value2;...".
• user-id – is a valid user ID. Unless this string is empty, ";UID=value" is appended to the
connection string.
• password – is the corresponding password for the user ID. Unless this string is empty,
";PWD=value" is appended to the connection string.
• options – is a hash of additional connection parameters such as DatabaseName,
DatabaseFile, and ConnectionName. These are appended to the connection string in the
format "option1=value1;option2=value2;...".
To demonstrate the connect function, make the iqdemo database, start the database server and
iqdemo database before running the sample Ruby scripts.
$IQDIR16/demo
mkiqdemo.sh
start_iq @iqdemo.cfg iqdemo.db
The following code sample opens and closes a connection to the iqdemo database. The string
"myserver" in the example below is the server name.
require 'dbi'
DBI.connect('DBI:SQLAnywhere:myserver', '<user_id>', '<password>')
Programming 595
Ruby Support
do |dbh|
if dbh.ping
print "Successfully Connected\n"
dbh.disconnect()
end
end
Optionally, you can specify a connection string in place of the server name. For example, in the
above script may be altered by replacing the first parameter to the connect function as follows:
require 'dbi'
DBI.connect('DBI:SQLAnywhere:SERVER=myserver;DBN=iqdemo',
'<user_id>', '<password>') do |dbh|
if dbh.ping
print "Successfully Connected\n"
dbh.disconnect()
end
end
The user ID and password cannot be specified in the connection string. Ruby DBI will
automatically fill in the username and password with defaults if these arguments are omitted,
so you should never include a UID or PWD connection parameter in your connection string. If
you do, an exception will be thrown.
The following example shows how additional connection parameters can be passed to the
connect function as a hash of key/value pairs.
require 'dbi'
DBI.connect('DBI:SQLAnywhere:myserver', '<user_id>', '<password>',
{ :ConnectionName => "RubyDemo",
:DatabaseFile => "iqdemo.db",
:DatabaseName => "iqdemo" }
) do |dbh|
if dbh.ping
print "Successfully Connected\n"
dbh.disconnect()
end
end
Selecting Data
Once you have obtained a handle to an open connection, you can access and modify data
stored in the database. Perhaps the simplest operation is to retrieve some rows and print them
out.
A SQL statement must be executed first. If the statement returns a result set, you use the
resulting statement handle to retrieve meta information about the result set and the rows of the
result set. The following example obtains the column names from the metadata and displays
the column names and values for each row fetched.
require 'dbi'
sth.fetch do |row|
print "\n"
sth.column_info.each_with_index do |info, i|
unless info["type_name"] == "LONG VARBINARY"
print "#{info["name"]}=#{row[i]}\n"
end
end
end
sth.finish
end
begin
dbh = DBI.connect('DBI:SQLAnywhere:demo', '<user_id>',
'<password>')
db_query(dbh, "SELECT * FROM Products")
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
puts "Error SQLSTATE: #{e.state}"
ensure
dbh.disconnect if dbh
end
The first few lines of output that appear are reproduced below.
# of Fields: 8
ID=300
Name=Tee Shirt
Description=Tank Top
Size=Small
Color=White
Quantity=28
UnitPrice=9.00
ID=301
Name=Tee Shirt
Description=V-neck
Size=Medium
Color=Orange
Quantity=54
UnitPrice=14.00
It is important to call finish to release the statement handle when you are done. If you do not,
then you may get an error like the following:
Resource governor for 'prepared statements' exceeded
To detect handle leaks, the SAP Sybase IQ database server limits the number of cursors and
prepared statements permitted to a maximum of 50 per connection by default. The resource
governor automatically generates an error if these limits are exceeded. If you get this error,
check for undestroyed statement handles. Use prepare_cached sparingly, as the statement
handles are not destroyed.
Programming 597
Ruby Support
If necessary, you can alter these limits by setting the max_cursor_count and
max_statement_count options.
Inserting Rows
Inserting rows requires a handle to an open connection. The simplest way to insert rows is to
use a parameterized INSERT statement, meaning that question marks are used as placeholders
for values. The statement is first prepared, and then executed once per new row. The new row
values are supplied as parameters to the execute method.
require 'dbi'
begin
dbh = DBI.connect('DBI:SQLAnywhere:demo', '<user_id>',
'<password>')
rows = [
[801,'Alex','Alt','5 Blue Ave','New York','NY','USA',
'10012','5185553434','BXM'],
[802,'Zach','Zed','82 Fair St','New York','NY','USA',
'10033','5185552234','Zap']
]
db_insert(dbh, rows)
dbh.commit
db_query(dbh, "SELECT * FROM Customers WHERE ID > 800")
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
puts "Error SQLSTATE: #{e.state}"
ensure
dbh.disconnect if dbh
end
The first two rows of the result set output from this Ruby program are shown below:
ID=300
Name=Tee Shirt
Description=Tank Top
Size=Small
Color=White
Quantity=28
UnitPrice=9.00
Programming 599
Ruby Support
ID=301
Name=Tee Shirt
Description=V-neck
Size=Medium
Color=Orange
Quantity=54
UnitPrice=14.00
sqlany_affected_rows
Returns the number of rows affected by execution of the prepared statement.
Syntax
sqlany_affected_rows ( $stmt )
Parameters
• $stmt – A statement that was prepared and executed successfully in which no result set
was returned. For example, an INSERT, UPDATE or DELETE statement was executed.
Returns
Returns a scalar value that is the number of rows affected, or -1 on failure.
Example
affected = api.sqlany_affected( stmt )
sqlany_bind_param Function
Binds a user-supplied buffer as a parameter to the prepared statement.
Syntax
sqlany_bind_param ( $stmt, $index, $param )
Parameters
• $stmt – A statement object returned by the successful execution of sqlany_prepare.
• $index – The index of the parameter. The number must be between 0 and
sqlany_num_params() - 1.
• $param – A filled bind object retrieved from sqlany_describe_bind_param.
Returns
Returns a scalar value that is 1 when successful or 0 when unsuccessful.
Example
stmt = api.sqlany_prepare(conn, "UPDATE Contacts
SET Contacts.ID = Contacts.ID + 1000
sqlany_clear_error Function
Clears the last stored error code.
Syntax
sqlany_clear_error ( $conn )
Parameters
• $conn – A connection object returned from sqlany_new_connection.
Returns
Returns nil.
Example
api.sqlany_clear_error( conn )
sqlany_client_version Function
Returns the current client version.
Syntax
sqlany_client_version ( )
Returns
Returns a scalar value that is the client version string.
Example
buffer = api.sqlany_client_version()
sqlany_commit Function
Commits the current transaction.
Syntax
sqlany_commit ( $conn )
Parameters
• $conn – The connection object on which the commit operation is to be performed.
Programming 601
Ruby Support
Returns
Returns a scalar value that is 1 when successful or 0 when unsuccessful.
Example
rc = api.sqlany_commit( conn )
sqlany_connect Function
Creates a connection to a SQL Anywhere database server using the specified connection
object and connection string.
Syntax
sqlany_connect ( $conn, $str )
Parameters
• $conn – The connection object created by sqlany_new_connection.
• $str – A SQL Anywhere connection string.
Returns
Returns a scalar value that is 1 if the connection is established successfully or 0 when the
connection fails. Use sqlany_error to retrieve the error code and message.
Example
# Create a connection
conn = api.sqlany_new_connection()
# Establish a connection
status = api.sqlany_connect( conn, "UID=DBA;PWD=sql" )
print "Connection status = #{status}\n"
sqlany_describe_bind_param Function
Describes the bind parameters of a prepared statement.
Syntax
sqlany_describe_bind_param ( $stmt, $index )
Parameters
• $stmt – A statement prepared successfully using sqlany_prepare.
• $index – The index of the parameter. The number must be between 0 and
sqlany_num_params() - 1.
Returns
Returns a 2-element array that contains 1 on success or 0 on failure as the first element and a
described parameter as the second element.
Remarks
This function allows the caller to determine information about prepared statement parameters.
The type of prepared statement (stored procedure or a DML), determines the amount of
information provided. The direction of the parameters (input, output, or input-output) are
always provided.
Example
stmt = api.sqlany_prepare(conn, "UPDATE Contacts
SET Contacts.ID = Contacts.ID + 1000
WHERE Contacts.ID >= ?" )
rc, param = api.sqlany_describe_bind_param( stmt, 0 )
print "Param name = ", param.get_name(), "\n"
print "Param dir = ", param.get_direction(), "\n"
param.set_value(50)
rc = api.sqlany_bind_param( stmt, 0, param )
sqlany_disconnect Function
Disconnects a SQL Anywhere connection. All uncommitted transactions are rolled back.
Syntax
sqlany_disconnect ( $conn )
Parameters
• $conn – A connection object with a connection established using sqlany_connect.
Returns
Returns a scalar value that is 1 on success or 0 on failure.
Example
# Disconnect from the database
status = api.sqlany_disconnect( conn )
print "Disconnect status = #{status}\n"
sqlany_error Function
Returns the last error code and message stored in the connection object.
Syntax
sqlany_error ( $conn )
Parameters
• $conn – A connection object returned from sqlany_new_connection.
Programming 603
Ruby Support
Returns
Returns a 2-element array that contains the SQL error code as the first element and an error
message string as the second element.
For the error code, positive values are warnings, negative values are errors, and 0 is success.
Example
code, msg = api.sqlany_error( conn )
print "Code=#{code} Message=#{msg}\n"
sqlany_execute Function
Executes a prepared statement.
Syntax
sqlany_execute ( $stmt )
Parameters
• $stmt – A statement prepared successfully using sqlany_prepare.
Returns
Returns a scalar value that is 1 on success or 0 on failure.
Remarks
You can use sqlany_num_cols to verify if the statement returned a result set.
Example
stmt = api.sqlany_prepare(conn, "UPDATE Contacts
SET Contacts.ID = Contacts.ID + 1000
WHERE Contacts.ID >= ?" )
rc, param = api.sqlany_describe_bind_param( stmt, 0 )
param.set_value(50)
rc = api.sqlany_bind_param( stmt, 0, param )
rc = api.sqlany_execute( stmt )
sqlany_execute_direct Function
Executes the SQL statement specified by the string argument.
Syntax
sqlany_execute_direct ( $conn, $sql )
Parameters
• $conn – A connection object with a connection established using sqlany_connect.
• $sql – A SQL string. The SQL string should not have parameters such as ?.
Returns
Returns a statement object or nil on failure.
Remarks
Use this function to prepare and execute a statement in one step. Do not use this function to
execute a SQL statement with parameters.
Example
stmt = api.sqlany_execute_direct( conn, "SELECT * FROM Employees" )
rc = api.sqlany_fetch_next( stmt )
rc, employeeID = api.sqlany_get_column( stmt, 0 )
rc, managerID = api.sqlany_get_column( stmt, 1 )
rc, surname = api.sqlany_get_column( stmt, 2 )
rc, givenName = api.sqlany_get_column( stmt, 3 )
rc, departmentID = api.sqlany_get_column( stmt, 4 )
print employeeID, ",", managerID, ",",
surname, ",", givenName, ",", departmentID, "\n"
sqlany_execute_immediate Function
Executes the specified SQL statement immediately without returning a result set. It is useful
for statements that do not return result sets.
Syntax
sqlany_execute_immediate ( $conn, $sql )
Parameters
• $conn – A connection object with a connection established using sqlany_connect.
• $sql – A SQL string. The SQL string should not have parameters such as ?.
Returns
Returns a scalar value that is 1 on success or 0 on failure.
Example
rc = api.sqlany_execute_immediate(conn, "UPDATE Contacts
SET Contacts.ID = Contacts.ID + 1000
WHERE Contacts.ID >= 50" )
sqlany_fetch_absolute Function
Moves the current row in the result set to the row number specified and then fetches the data at
that row.
Syntax
sqlany_fetch_absolute ( $stmt, $row_num )
Programming 605
Ruby Support
Parameters
• $stmt – A statement object that was executed by sqlany_execute or
sqlany_execute_direct.
• $row_num – The row number to be fetched. The first row is 1, the last row is -1.
Returns
Returns a scalar value that is 1 on success or 0 on failure.
Example
stmt = api.sqlany_execute_direct( conn, "SELECT * FROM Employees" )
# Fetch the second row
rc = api.sqlany_fetch_absolute( stmt, 2 )
rc, employeeID = api.sqlany_get_column( stmt, 0 )
rc, managerID = api.sqlany_get_column( stmt, 1 )
rc, surname = api.sqlany_get_column( stmt, 2 )
rc, givenName = api.sqlany_get_column( stmt, 3 )
rc, departmentID = api.sqlany_get_column( stmt, 4 )
print employeeID, ",", managerID, ",",
surname, ",", givenName, ",", departmentID, "\n"
sqlany_fetch_next Function
Returns the next row from the result set. This function first advances the row pointer and then
fetches the data at the new row.
Syntax
sqlany_fetch_next ( $stmt )
Parameters
• $stmt – A statement object that was executed by sqlany_execute or
sqlany_execute_direct.
Returns
Returns a scalar value that is 1 on success or 0 on failure.
Example
stmt = api.sqlany_execute_direct( conn, "SELECT * FROM Employees" )
# Fetch the second row
rc = api.sqlany_fetch_next( stmt )
rc, employeeID = api.sqlany_get_column( stmt, 0 )
rc, managerID = api.sqlany_get_column( stmt, 1 )
rc, surname = api.sqlany_get_column( stmt, 2 )
rc, givenName = api.sqlany_get_column( stmt, 3 )
rc, departmentID = api.sqlany_get_column( stmt, 4 )
print employeeID, ",", managerID, ",",
surname, ",", givenName, ",", departmentID, "\n"
sqlany_fini Function
Frees resources allocated by the API.
Syntax
sqlany_fini ( )
Returns
Returns nil.
Example
# Disconnect from the database
api.sqlany_disconnect( conn )
sqlany_free_connection Function
Frees the resources associated with a connection object.
Syntax
sqlany_free_connection ( $conn )
Parameters
• $conn – A connection object created by sqlany_new_connection.
Returns
Returns nil.
Example
# Disconnect from the database
api.sqlany_disconnect( conn )
Programming 607
Ruby Support
sqlany_free_stmt Function
Frees resources associated with a statement object.
Syntax
sqlany_free_stmt ( $stmt )
Parameters
• $stmt – A statement object returned by the successful execution of sqlany_prepare or
sqlany_execute_direct.
Returns
Returns nil.
Example
stmt = api.sqlany_prepare(conn, "UPDATE Contacts
SET Contacts.ID = Contacts.ID + 1000
WHERE Contacts.ID >= ?" )
rc, param = api.sqlany_describe_bind_param( stmt, 0 )
param.set_value(50)
rc = api.sqlany_bind_param( stmt, 0, param )
rc = api.sqlany_execute( stmt )
rc = api.sqlany_free_stmt( stmt )
sqlany_get_bind_param_info Function
Retrieves information about the parameters that were bound using sqlany_bind_param.
Syntax
sqlany_get_bind_param_info ( $stmt, $index )
Parameters
• $stmt – A statement successfully prepared using sqlany_prepare.
• $index – The index of the parameter. The number must be between 0 and
sqlany_num_params() - 1.
Returns
Returns a 2-element array that contains 1 on success or 0 on failure as the first element and a
described parameter as the second element.
Example
# Get information on first parameter (0)
rc, param_info = api.sqlany_get_bind_param_info( stmt, 0 )
print "Param_info direction = ", param_info.get_direction(), "\n"
print "Param_info output = ", param_info.get_output(), "\n"
sqlany_get_column Function
Returns the value fetched for the specified column.
Syntax
sqlany_get_column ( $stmt, $col_index )
Parameters
• $stmt – A statement object that was executed by sqlany_execute or
sqlany_execute_direct.
• $col_index – The number of the column to be retrieved. A column number is between 0
and sqlany_num_cols() - 1.
Returns
Returns a 2-element array that contains 1 on success or 0 on failure as the first element and the
column value as the second element.
Example
stmt = api.sqlany_execute_direct( conn, "SELECT * FROM Employees" )
# Fetch the second row
rc = api.sqlany_fetch_next( stmt )
rc, employeeID = api.sqlany_get_column( stmt, 0 )
rc, managerID = api.sqlany_get_column( stmt, 1 )
rc, surname = api.sqlany_get_column( stmt, 2 )
rc, givenName = api.sqlany_get_column( stmt, 3 )
rc, departmentID = api.sqlany_get_column( stmt, 4 )
print employeeID, ",", managerID, ",",
surname, ",", givenName, ",", departmentID, "\n"
sqlany_get_column_info Function
Gets column information for the specified result set column.
Syntax
sqlany_get_column_info ( $stmt, $col_index )
Parameters
• $stmt – A statement object that was executed by sqlany_execute or
sqlany_execute_direct.
• $col_index – The column number between 0 and sqlany_num_cols() - 1.
Returns
Returns a 9-element array of information describing a column in a result set. The first element
contains 1 on success or 0 on failure. The array elements are described in the following table.
Programming 609
Ruby Support
Example
# Get column info for first column (0)
rc, col_num, col_name, col_type, col_native_type, col_precision,
col_scale,
col_size, col_nullable = api.sqlany_get_column_info( stmt, 0 )
sqlany_get_next_result Function
Advances to the next result set in a multiple result set query.
Syntax
sqlany_get_next_result ( $stmt )
Parameters
• $stmt – A statement object executed by sqlany_execute or sqlany_execute_direct.
Returns
Returns a scalar value that is 1 on success or 0 on failure.
Example
stmt = api.sqlany_prepare(conn, "call two_results()" )
rc = api.sqlany_execute( stmt )
# Fetch from first result set
rc = api.sqlany_fetch_absolute( stmt, 3 )
# Go to next result set
rc = api.sqlany_get_next_result( stmt )
sqlany_init Function
Initializes the interface.
Syntax
sqlany_init ( )
Returns
Returns a 2-element array that contains 1 on success or 0 on failure as the first element and the
Ruby interface version as the second element.
Example
# Load the SQLAnywhere gem
begin
require 'rubygems'
gem 'sqlanywhere'
unless defined? SQLAnywhere
require 'sqlanywhere'
end
end
# Create an interface
api = SQLAnywhere::SQLAnywhereInterface.new()
# Initialize the interface (loads the DLL/SO)
SQLAnywhere::API.sqlany_initialize_interface( api )
# Initialize our api object
api.sqlany_init()
sqlany_new_connection Function
Creates a connection object.
Syntax
sqlany_new_connection ()
Returns
Returns a scalar value that is a connection object.
Remarks
A connection object must be created before a database connection is established. Errors can be
retrieved from the connection object. Only one request can be processed on a connection at a
time.
Example
# Create a connection
conn = api.sqlany_new_connection()
# Establish a connection
Programming 611
Ruby Support
sqlany_num_cols Function
Returns number of columns in the result set.
Syntax
sqlany_num_cols ( $stmt )
Parameters
• $stmt – A statement object executed by sqlany_execute or sqlany_execute_direct.
Returns
Returns a scalar value that is the number of columns in the result set, or -1 on a failure.
Example
stmt = api.sqlany_execute_direct( conn, "SELECT * FROM Employees" )
# Get number of result set columns
num_cols = api.sqlany_num_cols( stmt )
sqlany_num_params Function
Returns the number of parameters that are expected for a prepared statement.
Syntax
sqlany_num_params ( $stmt )
Parameters
• $stmt – A statement object returned by the successful execution of sqlany_prepare.
Returns
Returns a scalar value that is the number of parameters in a prepared statement, or -1 on a
failure.
Example
stmt = api.sqlany_prepare(conn, "UPDATE Contacts
SET Contacts.ID = Contacts.ID + 1000
WHERE Contacts.ID >= ?" )
num_params = api.sqlany_num_params( stmt )
sqlany_num_rows Function
Returns the number of rows in the result set.
Syntax
sqlany_num_rows ( $stmt )
Parameters
• $stmt – A statement object executed by sqlany_execute or sqlany_execute_direct.
Returns
Returns a scalar value that is the number of rows in the result set. If the number of rows is an
estimate, the number returned is negative and the estimate is the absolute value of the returned
integer. The value returned is positive if the number of rows is exact.
Remarks
By default, this function only returns an estimate. To return an exact count, set the
ROW_COUNTS option on the connection.
A count of the number of rows in a result set can be returned only for the first result set in a
statement that returns multiple result sets. If sqlany_get_next_result is used to move to the
next result set, sqlany_num_rows will still return the number of rows in the first result set.
Example
stmt = api.sqlany_execute_direct( conn, "SELECT * FROM Employees" )
# Get number of rows in result set
num_rows = api.sqlany_num_rows( stmt )
sqlany_prepare Function
Prepares the supplied SQL string.
Syntax
sqlany_prepare ( $conn, $sql )
Parameters
• $conn – A connection object with a connection established using sqlany_connect.
• $sql – The SQL statement to be prepared.
Returns
Returns a scalar value that is the statement object, or nil on failure.
Remarks
The statement associated with the statement object is executed by sqlany_execute. You can
use sqlany_free_stmt to free the resources associated with the statement object.
Example
stmt = api.sqlany_prepare(conn, "UPDATE Contacts
SET Contacts.ID = Contacts.ID + 1000
WHERE Contacts.ID >= ?" )
rc, param = api.sqlany_describe_bind_param( stmt, 0 )
param.set_value(50)
Programming 613
Ruby Support
sqlany_rollback Function
Rolls back the current transaction.
Syntax
sqlany_rollback ( $conn )
Parameters
• $conn – The connection object on which the rollback operation is to be performed.
Returns
Returns a scalar value that is 1 on success, 0 on failure.
Example
rc = api.sqlany_rollback( conn )
sqlany_sqlstate Function
Retrieves the current SQLSTATE.
Syntax
sqlany_sqlstate ( $conn )
Parameters
• $conn – A connection object returned from sqlany_new_connection.
Returns
Returns a scalar value that is the current five-character SQLSTATE.
Example
sql_state = api.sqlany_sqlstate( conn )
Column Types
The following Ruby class defines the column types returned by some SQL Anywhere Ruby
functions.
class Types
A_INVALID_TYPE = 0
A_BINARY = 1
A_STRING = 2
A_DOUBLE = 3
A_VAL64 = 4
A_UVAL64 = 5
A_VAL32 = 6
A_UVAL32 = 7
A_VAL16 = 8
A_UVAL16 = 9
A_VAL8 = 10
A_UVAL8 = 11
end
388 DT_TIME
390 DT_TIMESTAMP_STRUCT
392 DT_TIMESTAMP
448 DT_VARCHAR
452 DT_FIXCHAR
456 DT_LONGVARCHAR
460 DT_STRING
480 DT_DOUBLE
482 DT_FLOAT
484 DT_DECIMAL
496 DT_INT
500 DT_SMALLINT
524 DT_BINARY
528 DT_LONGBINARY
600 DT_VARIABLE
604 DT_TINYINT
608 DT_BIGINT
612 DT_UNSINT
616 DT_UNSSMALLINT
620 DT_UNSBIGINT
Programming 615
Ruby Support
628 DT_NSTRING
632 DT_NFIXCHAR
636 DT_NVARCHAR
640 DT_LONGNVARCHAR
Programming 617
Sybase Open Client Support
Network services
Open Client network services include Sybase Net-Library, which provides support for
specific network protocols such as TCP/IP and DECnet. The Net-Library interface is invisible
to application developers. However, on some platforms, an application may need a different
Net-Library driver for different system network configurations. Depending on your host
platform, the Net-Library driver is specified either by the system's Sybase configuration or
when you compile and link your programs.
Instructions for driver configuration can be found in the Open Client/Server Configuration
Guide.
Instructions for building Client-Library programs can be found in the Open Client/Server
Programmer's Supplement.
string varchar
timestamp datetime
Programming 619
Sybase Open Client Support
Data type Open Client Open Client SAP Sybase SAP Sybase
lower range upper range IQ lower IQupper
range range
MONEY -922 377 203 685 922 377 203 685 -999 999 999 999 999 999 999 999
477.5808 477.5807 999.9999 999.9999
SMALLMONEY -214 748.3648 214 748.3647 -999 999.9999 -999 999.9999
DATETIME [1] January 1, 1753 December 31, January 1, 0001 December 31,
9999 9999
SMALLDATE- January 1, 1900 June 6, 2079 January 1, 0001 December 31,
TIME 9999
[1] For versions earlier than OpenClient 15.5; otherwise, the full range of dates from
0001-01-01 to 9999-12-31 is supported.
Example
For example, the Open Client MONEY and SMALLMONEY data types do not span the entire
numeric range of their underlying SAP Sybase IQ implementations. Therefore, it is possible to
have a value in an SAP Sybase IQ column which exceeds the boundaries of the Open Client
data type MONEY. When the client fetches any such offending values via SAP Sybase IQ, an
error is generated.
Timestamps
TIMESTAMP values inserted into or retrieved from SAP Sybase IQ will have the date portion
restricted to January 1, 1753 or later and the time version restricted to 1/300th of a second
precision if the client is using Open Client 15.1 or earlier. If, however, the client is using Open
Client 15.5 or later, then no restriction will apply to TIMESTAMP values.
CS_UNUSED);
ret = ct_send(cmd);
Programming 621
Sybase Open Client Support
Storing prefetched rows at the client side reduces the number of calls to the server and this
improves overall throughput and turnaround time. Prefetched rows are not immediately
passed on to the application; they are stored in a buffer at the client side ready for use.
The setting of the prefetch database option controls prefetching of rows for other
interfaces. It is ignored by Open Client connections. The CS_CURSOR_ROWS setting is
ignored for non-unique, updatable cursors.
3. To open a cursor in Open Client, use ct_cursor with CS_CURSOR_OPEN as the type
parameter.
4. To fetch each row in to the application, use ct_fetch.
5. To close a cursor, you use ct_cursor with CS_CURSOR_CLOSE.
6. In Open Client, you also need to deallocate the resources associated with a cursor. You do
this by using ct_cursor with CS_CURSOR_DEALLOC. You can also use
CS_CURSOR_CLOSE with the additional parameter CS_DEALLOC to perform these
operations in a single step.
CS_CSR_ABS
CS_CSR_FIRST
CS_CSR_LAST
CS_CSR_PREV
CS_CSR_REL
CS_DATA_BOUNDARY
CS_DATA_SENSITIVITY
CS_OPT_FORMATONLY
CS_PROTO_DYNPROC
CS_REG_NOTIF
CS_REQ_BCP
• Security options, such as SSL, are not supported. However, password encryption is
supported.
• Open Client applications can connect to SAP Sybase IQ using TCP/IP.
For more information about capabilities, see the Open Server Server-Library C Reference
Manual.
• When the CS_DATAFMT is used with the CS_DESCRIBE_INPUT, it does not return the
data type of a column when a parameterized variable is sent to SAP Sybase IQ as input.
Programming 623
Sybase Open Client Support
Note: Use the iqsrv16 command to start a database server that can be accessed on a
network.
The -xs http(port=8082) option instructs the server to listen for HTTP requests on port
8082. Use a different port number if a web server is already running on port 8082.
2. Use the CREATE SERVICE statement to create a web service that responds to incoming
web browser requests.
a. Connect to the demo.db database using Interactive SQL by running the following
command:
Programming 625
HTTP Web Services
dbisql -c "dbf=iqdemo.db;uid=<user_id>;pwd=<password>"
b. Create a new web service in the database.
Execute the following SQL statement in Interactive SQL:
CREATE SERVICE SampleWebService
TYPE 'web-service-type-clause'
AUTHORIZATION OFF
USER DBA
AS SELECT 'Hello world!';
Replace web-service-type-clause with the desired web service type. The HTML type
clause is recommended for web browser compatibility. Other general HTTP web
service type clauses include XML, RAW, and JSON.
The CREATE SERVICE statement creates the SampleWebService web service,
which returns the result set of the SELECT statement. In this example, the statement
returns "Hello world!"
The AUTHORIZATION OFF clause indicates that authorization is not required to
access the web service.
The USER DBA statement indicates that the service statement should be run under the
DBA login name.
The AS SELECT clause allows the service to select from a table or function, or view
data directly. Use AS CALL as an alternative clause to call a stored procedure.
3. View the web service in a web browser.
On the computer running the SAP Sybase IQ HTTP web server, open a web browser, such
as Internet Explorer or Firefox, and go to the following URL:
http://localhost:8082/demo/SampleWebService
This URL directs your web browser to the HTTP web server on port 8082.
SampleWebService prints "Hello world". The result set output is displayed in the
format specified by the web-service-type-clause from step 2.
Replace protocol-type and protocol-options with one of the following supported protocols
and any appropriate protocol options:
• HTTP – Use this protocol to listen for HTTP connections. Here is an example.
iqsrv16 -xs HTTP(PORT=8082) services.db
• HTTPS – Use this protocol to listen for HTTPS connections. SSL version 3.0 and TLS
version 1.0/1.1 are supported. Here is an example.
iqsrv16 -xs "HTTPS(FIPS=N;PORT=8082;IDENTITY="%ALLUSERSPROFILE
%"\SybaseIQ\samples\Certificates
\rsaserver.id;IDENTITY_PASSWORD=test)" services.db
Note: Network protocol options are available for each supported protocol. These options
allow you to control protocol behavior and can be configured at the command line when you
launch your database server.
This command starts a database server that enables the HTTPS web service protocol for the
your-database-name.db database. The network protocol options indicate that the web
server should perform the following tasks:
The following list identifies the network protocol options that are commonly used for web
service protocols:
Programming 627
HTTP Web Services
using multiple instances of the -xs database server option. This task is performed by
specifying a unique port number for each HTTP web server.
Example
In this example, the following command line starts two HTTP web services—one for your-
first-database.db and one for your-second-database.db:
iqsrv16 -xs http(port=80;dbn=your-first-
database),http(port=8800;dbn=your-second-database)
your-first-database.db your-second-database.db
Programming 629
HTTP Web Services
Content-Type header to specify the MIME type, allowing web browsers to correctly
display the result set.
• JSON – The result set of a statement, function, or procedure is returned in JSON
(JavaScript Object Notation). JavaScript Object Notation (JSON) is a language-
independent, text-based data interchange format developed for the serialization of
JavaScript data. JSON represents four basic types: strings, numbers, booleans, and NULL.
JSON also represents two structured types: objects and arrays. For more information about
JSON, see http://www.json.org/.
This service is used by AJAX to make HTTP calls to web applications. For an example of
the JSON type, see %ALLUSERSPROFILE%\SybaseIQ\samples\SQLAnywhere
\HTTP\json_sample.sql.
• SOAP – The result set of a statement, function, or procedure is returned as a SOAP
response. SOAP services provide a common data interchange standard to provide data
access to disparate client applications that support SOAP. SOAP request and response
envelopes are transported as an XML payload using HTTP (SOAP over HTTP). A request
to a SOAP service must be a valid SOAP request, not a general HTTP request. The output
of SOAP services can be adjusted using the FORMAT and DATATYPE attributes of the
CREATE or ALTER SERVICE statement.
• DISH – A DISH service (Determine SOAP Handler) is an SAP Sybase IQ SOAP endpoint.
The DISH service exposes the WSDL (Web Services Description Language) document
that describes all SOAP Operations (SAP Sybase IQ SOAP services) accessible through it.
A SOAP client toolkit builds the client application with interfaces based on the WSDL.
The SOAP client application directs all SOAP requests to the SOAP endpoint (the SAP
Sybase IQ DISH service).
Example
The following example illustrates the creation of a general HTTP web service that uses the
RAW service type:
CREATE PROCEDURE sp_echotext(str LONG VARCHAR)
BEGIN
CALL sa_set_http_header( 'Content-Type', 'text/plain' );
SELECT str;
END;
The CREATE SERVICE statement creates a new web service named SampleWebService
and returns the result set of sql-statement. You can replace sql-statement with either a
SELECT statement to select data from a table or view directly, or a CALL statement to call a
stored procedure in the database.
Programming 631
HTTP Web Services
Replace web-service-type-clause with the desired web service type. Valid clauses for HTTP
web services include HTML, XML, RAW and JSON.
You can view the generated result set for the SampleWebService service by accessing the
service in a web browser.
The first CREATE SERVICE statement creates a new SOAP service named Samples/
TestSoapOp.
The second CREATE SERVICE statement creates a new DISH service named
dnet_endpoint. The Samples portion of the GROUP clause identifies the group of
SOAP services to expose. You can view the WSDL document generated by the DISH service.
When running your SAP Sybase IQ web server on a computer, you can access the service
using the http://localhost:port-number/dnet_endpoint URL, where port-
number is the port number that the server is running on.
In this example, the SOAP service does not contain a FORMAT clause to indicate a SOAP
response format. Therefore, the SOAP response format is dictated by the DISH service, which
does not override the FORMAT clause of the SOAP service. This feature allows you to create
homogeneous DISH services where each DISH endpoint can serve SOAP clients with varying
capabilities.
Programming 633
HTTP Web Services
The URL ON portion specifies that the full path component is made accessible by an HTTP
variable named URL.
Execute the following SQL statement to create a table for storing page content. In this
example, the page content is defined by its URL, MIME-type, and the content itself.
CREATE TABLE Page_Content (
url VARCHAR(1024) NOT NULL PRIMARY KEY,
content_type VARCHAR(128) NOT NULL,
image LONG VARCHAR NOT NULL
);
Execute the following SQL statements to populate the table. In this example, the intent is to
define the content to be provided to the HTTP client when the index.html page is requested.
INSERT INTO Page_Content
VALUES(
'index.html',
'text/html',
'<html><body><h1>Hello World</h1></body></html>'
);
COMMIT;
Execute the following SQL statements to implement the PageContent procedure, which
accepts the url host variable that is passed through to the root web service:
Programming 635
HTTP Web Services
The root web service calls the PageContent procedure when a request to the HTTP
server does not match any other defined web service URL. The procedure checks if the client-
supplied URL matches a url in the Page_Content table. The SELECT statement sends a
response to the client. If the client-supplied URL was not found in the table, a generic 404 -
Page Not Found html page is built and sent to the client.
Some browsers will respond to the 404 status with their own page, so there is no guarantee that
the generic page will be displayed.
In the error message, the HTML_ENCODE function is used to encode the special characters
in the client-supplied URL.
The @HttpStatus header is used to set the status code returned with the request. A 404 status
indicates a Not Found error, and a 200 status indicates OK. The 'Content-Type' header is used
to set the content type returned with the request. In this example, the content (MIME) type of
the index.html page is text/html.
ALTER SERVICE statement [HTTP web serv- Alters an existing HTTP web service.
ice]
ALTER SERVICE statement [SOAP web serv- Alters an existing HTTP over SOAP or DISH
ice] service.
Programming 637
HTTP Web Services
Web services can only utilize a connection pool when they are defined with
AUTHORIZATION OFF.
A database connection within a pool is not updated when changes occur to database and
connection options.
In this example, the web service calls the HomePage stored procedure, which is required to
define a single URL parameter that receives the PATH component of the URL.
The following example illustrates how to format web page output in HTML using the text/
html MIME-type with the sa_set_http_header system procedure:
CREATE PROCEDURE HomePage (IN url LONG VARCHAR)
RESULT (html_doc XML)
BEGIN
CALL sa_set_http_header ( 'Content-Type', 'text/html' );
-- Your SQL code goes here.
...
END
Since element content is always escaped unless the data type is XML, the above example uses
the CAST function. Otherwise, special characters are escaped (for example, < for <).
Programming 639
HTTP Web Services
Service host parameters are mapped in the declaration order of procedure parameters. In the
above example, the user_name and table_name host parameters map to the username
and tblname parameters, respectively.
How to Access HTTP Variables and Headers Using Web Service Functions
The HTTP_VARIABLE, NEXT_HTTP_VARIABLE, HTTP_HEADER,
NEXT_HTTP_HEADER functions can be used to iterate through the variables and headers
supplied by the client.
The following example illustrates how to retrieve three attributes from header-field values
associated with the image variable:
SET v_name = HTTP_VARIABLE( 'image', NULL, 'Content-Disposition' );
SET v_type = HTTP_VARIABLE( 'image', NULL, 'Content-Type' );
SET v_image = HTTP_VARIABLE( 'image', NULL, '@BINARY' );
Supplying an integer as the second parameter allows you to retrieve additional values. The
third parameter allows you to retrieve header-field values from multi-part requests. Supply the
name of a header field to retrieve its value.
Accept-Language en-us
Programming 641
HTTP Web Services
Host localhost:8080
Connection Keep-Alive
@HttpURI /demo/ShowHTTPHeaders
@HttpVersion HTTP/1.1
@HttpQueryString id=-123&version=109&lang=en
You can use the @HttpStatus special header to set the status code of the request being
processed.
The following example illustrates how to format header names and values into an HTML
table.
Create the ShowHTTPHeaders web service:
CREATE SERVICE ShowHTTPHeaders
TYPE 'RAW'
AUTHORIZATION OFF
USER DBA
AS CALL HTTPHeaderExample();
END LOOP;
SELECT XMLELEMENT( name "table",
XMLATTRIBUTES( '' AS "BORDER",
'10' AS "CELLPADDING",
'0' AS "CELLSPACING" ),
XMLELEMENT( name "th",
XMLATTRIBUTES( 'left' AS "align",
'top' AS "valign" ),
'Header Name' ),
XMLELEMENT( name "th",
XMLATTRIBUTES( 'left' AS "align",
'top' AS "valign" ),
'Header Value' ),
XMLELEMENT( name "th",
XMLATTRIBUTES( 'left' AS "align",
'top' AS "valign" ),
'HTTP Query String' ),
table_rows );
END;
Access the ShowHTTPHeaders in a web browser to see the request headers arranged in an
HTML table.
Calling this function repeatedly returns all the header fields exactly once, but not necessarily
in the order they appear in the SOAP request.
Programming 643
HTTP Web Services
The SOAP_HEADER function returns the value of the named SOAP header field, or NULL if
not called from an SOAP service. It is used when processing an SOAP request via a web
service. If a header for the given field-name does not exist, the return value is NULL.
The example searches for a SOAP header named Authentication. When it finds this header, it
extracts the value for entire SOAP header and the values of the @namespace and
mustUnderstand attributes. The SOAP header value might look something like this XML
string:
<Authentication xmlns="CustomerOrderURN" mustUnderstand="1">
<userName pwd="none">
<first>John</first>
<last>Smith</last>
</userName>
</Authentication>
Using the sample SOAP header value shown above, the SELECT statement would create a
result set as follows:
pwd first_name last_name
none John Smith
A cursor is declared on this result set and the three column values are fetched into three
variables. At this point, you have all the information of interest that was passed to the web
service.
Example
The following example illustrates how a web server can process SOAP requests containing
parameters, and SOAP headers. The example implements an addItem SOAP operation that
takes two parameters: amount of type int and item of type string. The sp_addItems
procedure processes an Authentication SOAP header extracting the first and last name of the
user. The values are used to populate a SOAP response Validation header via the
sa_set_soap_header system procedure. The response is a result of three columns: quantity,
item and status with types INT, LONG VARCHAR and LONG VARCHAR respectively.
// create the SOAP service
CREATE SERVICE addItems
TYPE 'SOAP'
FORMAT 'CONCRETE'
AUTHORIZATION OFF
USER DBA
AS CALL sp_addItems( :amount, :item );
// create the procedure that will process the SOAP requests for the
addItems service
CREATE PROCEDURE sp_addItems(count INT, item LONG VARCHAR)
RESULT(quantity INT, item LONG VARCHAR, status LONG VARCHAR)
BEGIN
DECLARE hd_key LONG VARCHAR;
DECLARE hd_entry LONG VARCHAR;
DECLARE pwd LONG VARCHAR;
DECLARE first_name LONG VARCHAR;
DECLARE last_name LONG VARCHAR;
DECLARE xpath LONG VARCHAR;
DECLARE authinfo LONG VARCHAR;
DECLARE namespace LONG VARCHAR;
DECLARE mustUnderstand LONG VARCHAR;
header_loop:
LOOP
SET hd_key = next_soap_header( hd_key );
IF hd_key IS NULL THEN
// no more header entries.
leave header_loop;
END IF;
IF hd_key = 'Authentication' THEN
SET hd_entry = soap_header( hd_key );
SET xpath = '/*:' || hd_key || '/*:userName';
SET namespace = soap_header( hd_key, 1, '@namespace' );
SET mustUnderstand = soap_header( hd_key, 1,
'mustUnderstand' );
BEGIN
// parse for the pieces that you are interested in
DECLARE crsr CURSOR FOR SELECT * FROM
OPENXML( hd_entry, xpath )
WITH ( pwd LONG VARCHAR '@*:pwd',
first_name LONG VARCHAR '*:first/text()',
last_name LONG VARCHAR '*:last/text()');
OPEN crsr;
FETCH crsr INTO pwd, first_name, last_name;
CLOSE crsr;
END;
// build a response header, based on the pieces from the
request header
SET authinfo = XMLELEMENT( 'Validation',
XMLATTRIBUTES(
namespace as xmlns,
mustUnderstand as mustUnderstand ),
XMLELEMENT( 'first', first_name ),
XMLELEMENT( 'last', last_name ) );
Programming 645
HTTP Web Services
The request is processed as a standard session-less request if an XYZ database connection does
not exist.
Example
The following code illustrates how to create a RAW web service that creates and deletes
sessions. A connection scope variable named request_count is incremented each time an
HTTP request is made while specifying a valid SessionID.
CREATE SERVICE mysession
TYPE 'RAW'
AUTHORIZATION OFF
USER DBA
AS CALL mysession_proc();
Programming 647
HTTP Web Services
SELECT body;
END;
The SessionID is represented as an empty string if the session_id is not defined for the
connection, making a sessionless connection.
The sa_set_http_option system procedure returns an error if the session_id is owned by
another HTTP request.
supported with the 'Set-Cookie' HTTP response header of the sa_set_http_header system
procedure.
Note: You cannot rely on cookie state management when cookies can be disabled in the client
application or web browser. Support for both URL and cookie state management is
recommended. The URL-supplied session ID is used when session IDs are provided by both
the URL and a cookie.
Example
The following example illustrates unique session ID creation within an HTTP web server SQL
function where session IDs can be provided by a URL or a cookie:
CREATE FUNCTION set_session_cookie()
RETURNS LONG VARCHAR
BEGIN
DECLARE session_id LONG VARCHAR;
DECLARE tm TIMESTAMP;
SET tm = NOW(*);
SET session_id = 'session_' ||
CONVERT( VARCHAR, SECONDS(tm) * 1000 + DATEPART( MILLISECOND,
tm ) );
CALL sa_set_http_option( 'SessionID', session_id );
CALL sa_set_http_header( 'Set-Cookie',
'sessionid=' || session_id || ';' ||
'max-age=60;' ||
'path=/session;' );
SELECT CONNECTION_PROPERTY( 'SessionID' ) INTO session_id;
RETURN( session_id );
END;
Programming 649
HTTP Web Services
When an HTTP session is deleted or the SessionID is changed, any pending HTTP requests
that are waiting on the session queue are released and allowed to run outside of a session
context. The pending requests do not reuse the same database connection.
A session ID cannot be set to an existing session ID. Pending requests referring to the old
SessionID are released to run as session-less requests when a SessionID has changed.
Subsequent requests referring to the new SessionID reuse the same database connection
instantiated by the old SessionID.
The following conditions are applied when deleting or changing an HTTP session:
• The behavior differs depending on whether the current request had inherited a session
whereby a database connection belonging to a session was acquired, or whether a session-
less request had instantiated a new session. If the request began as session-less, then the act
of creating or deleting a session occurs immediately. If the request has inherited a session,
then a change in the session state, such as deleting the session or changing the SessionID,
only occurs after the request terminates and its changes have been committed. The
difference in behavior addresses processing anomalies that may occur if a client makes
simultaneous requests using the same SessionID.
• Changing a session to a SessionID of the current session (has no pending session) is not an
error and has no substantial effect.
• Changing a session to a SessionID in use by another HTTP request is an error.
• Changing a session when a change is already pending results in the pending session being
deleted and new pending session being created. The pending session is only activated once
the request successfully terminates.
• Changing a session with a pending session back to its original SessionID results in the
pending session being deleted without any change to the current session.
A web application can require a means to track active session usage within the HTTP web
server. Session data can be found using the NEXT_CONNECTION function call to iterate
through the active database connections and checking for session related properties such as
SessionID.
The following SQL statements illustrate how to track an active session:
CREATE VARIABLE conn_id LONG VARCHAR;
CREATE VARIABLE the_sessionID LONG VARCHAR;
SELECT NEXT_CONNECTION( NULL, NULL ) INTO conn_id;
conn_loop:
LOOP
IF conn_id IS NULL THEN
LEAVE conn_loop;
END IF;
SELECT CONNECTION_PROPERTY( 'SessionID', conn_id )
INTO the_sessionID;
IF the_sessionID != '' THEN
PRINT 'conn_id = %1!, SessionID = %2!', conn_id,
the_sessionID;
ELSE
PRINT 'conn_id = %1!', conn_id;
END IF;
SELECT NEXT_CONNECTION( conn_id, NULL ) INTO conn_id;
END LOOP conn_loop;
PRINT '\n';
If you examine the database server messages window, you see data that is similar to the
following output:
conn_id = 30
conn_id = 29, SessionID = session_63315442223323
conn_id = 28, SessionID = session_63315442220088
conn_id = 25, SessionID = session_63315441867629
Explicitly dropping a connection that belongs to a session causes the connection to be closed
and the session to be deleted. If the connection being dropped is currently active in servicing
an HTTP request, the request is marked for deletion and the connection is sent a cancel signal
to terminate the request. When the request terminates, the session is deleted and the
Programming 651
HTTP Web Services
connection closed. Deleting the session causes any pending requests on that session's queue to
be re-queued.
In the event the connection is currently inactive, the session is marked for deletion and re-
queued to the beginning of the session timeout queue. The session and the connection are
deleted in the next timeout cycle (normally within 5 seconds). Any session marked for
deletion cannot be used by a new HTTP request.
All sessions are lost when the database is stopped.
You can use the 'AcceptCharset' option of the sa_set_http_option system procedure to specify
the character-set encoding preference when character-set conversion is enabled.
The following example illustrates how to specify the web service character set encoding
preference to ISO-8859-5, if supported; otherwise, set it to UTF-8:
CALL sa_set_http_option('AcceptCharset', 'iso-8859-5, utf-8');
Character sets are prioritized by server preference but the selection also considers the client's
Accept-Charset criteria. The most favored character set according to the client that is also
specified by this option is used.
There are also many system procedures available for web services.
Programming 653
HTTP Web Services
The following is a list of useful runtime HTTP request connection properties that are
commonly used for web service applications:
• HttpServiceName – Returns the service name origin for a web application.
• AuthType – Returns the type of authentication used when connecting.
• ServerPort – Returns the database server's TCP/IP port number or 0.
• ClientNodeAddress – Returns the node for the client in a client/server connection.
• ServerNodeAddress – Returns the node for the server in a client/server connection.
• BytesReceived – Returns the number of bytes received during client/server
communications.
The following is a list of options that are commonly used in HTTP servers for application
configuration:
• http_connection_pool_basesize – Specifies the nominal threshold size of database
connections.
• http_connection_pool_timeout – Specifies the maximum duration that an unused
connection can be retained in the connection pool.
• http_session_timeout – Specifies the default timeout duration, in minutes, that the HTTP
session persists during inactivity.
• request_timeout – Controls the maximum time a single request can run.
• webservice_namespace_host – Specifies the hostname to be used as the XML
namespace within specification for DISH services.
functions and procedures in your database, but content can also be generated with a URL that
specifies a SQL statement.
lternatively, or in conjunction, you can define the root web service, which processes all
HTTP requests that are not processed by a dedicated service. The root web service would
typically inspect the request URL and headers to determine how to process the request.
URLs uniquely specify resources such as html content available through HTTP or secured
HTTPS requests. This section explains how to format the URL syntax in your web browser so
that you can access the web services defined on your SAP Sybase IQ HTTP web server.
Note: The information in this section applies to HTTP web servers that use general HTTP web
service types, such as RAW, XML, and HTML, and DISH services. You cannot use a browser
to issue SOAP requests. JSON services return result sets for consumption by web service
applications using AJAX.
Syntax
{http|https}://host-name[:port-number][/dbn]/service-name[/path-
name|?url-query]
Parameters
• host-name and port-number – Specifies the location of the web server and, optionally,
the port number if it is not defined as the default HTTP or HTTPS port numbers. The
host-name can be the IP address of the computer running the web server. The port-number
must match the port number used when you started the web server.
• dbn – Specifies the name of a database. This database must be running on the web server
and contain web services.
You do not need to specify dbn if the web server is running only one database or if the
database name was specified for the given HTTP/HTTPS listener of the protocol option.
• service-name – Specifies the name of the web service to access. This web service must
exist in the database specified by dbn. Slash characters ( / ) are permitted when you create
or alter a web service, so you can use them as part of the service-name. SAP Sybase IQ
matches the remainder of the URL with the defined services.
The client request is processed if a service-name is not specified and the root web service
is defined. A 404 Not Found error is returned if the server cannot identify an
applicable service to process the request. As a side-effect, if the root web service does
exist and cannot process the request based on the URL criteria, then it is responsible for
generating the 404 Not Found error.
• path-name – After resolving the service name, the remaining slash delimited path can be
accessed by a web service procedure. If the service was created with URL ON, then the
whole path is accessible using a designated URL HTTP variable. If the service was created
with URL ELEMENTS, then each path element can be accessed using designated HTTP
variables URL1 to URL10.
Programming 655
HTTP Web Services
Path element variables can be defined as host variables within the parameter declaration of
the service statement definition. Alternatively, or additionally, HTTP variables can be
accessed from within a stored procedure using the HTTP_VARIABLE function call.
The following example illustrates the SQL statement used to create a web service where
the URL clause is set to ELEMENTS:
CREATE SERVICE TestWebService
TYPE 'HTML'
URL ELEMENTS
AUTHORIZATION OFF
USER DBA
AS CALL TestProcedure ( :url1, :url2 );
This TestWebService web service calls a procedure that explicitly references the
url1 and url2 host variables.
You can access this web service using the following URL, assuming that
TestWebService is running on the demo database from localhost through the
default port:
http://localhost/demo/TestWebService/Assignment1/Assignment2/
Assignment3
This URL accesses TestWebService, which runs TestProcedure and assigns the
Assignment1 value to url1, and the Assignment2 value to url2. Optionally,
TestProcedure can access other path elements using the HTTP_VARIABLE
function. For example, the HTTP_VARIABLE( 'url3' ) function call returns
Assignment3.
• url-query – An HTTP GET request may follow a path with a query component that
specifies HTTP variables. Similarly, the body of a POST request using a standard
application/x-www-form-urlencoded Content-Type can pass HTTP variables within the
request body. In either case, HTTP variables are passed as name/value pairs where the
variable name is delimited from its value with an equals signs. Variables are delimited with
an ampersand.
HTTP variables can be explicitly declared as host variables within the parameter list of the
service-statement, or accessed using the HTTP_VARIABLE function from within the
stored procedure of the service statement.
For example, the following SQL statement creates a web service that requires two host
variables. Host variables are identified with a colon (:) prefix.
CREATE SERVICE ShowSalesOrderDetail
TYPE 'HTML'
URL OFF
AUTHORIZATION OFF
USER DBA
AS CALL ShowSalesOrderDetail( :customer_id, :product_id );
Remarks
The web browser prompts for user name and password when required to connect to the server.
The browser then base64 encodes the user input within an Authorization request header and
resends the request.
If your web service URL clause is set to ON or ELEMENTS, the URL syntax properties of
path-name and url-query can be used simultaneously so that the web service is accessible
using one of several different formatting options. When using these syntax properties
simultaneously, the path-name format must be used first followed by the url-query format.
In the following example, this SQL statement creates a web service where the URL clause is
set to ON, which defines the url variable:
CREATE SERVICE ShowSalesOrderDetail
TYPE 'HTML'
URL ON
AUTHORIZATION OFF
USER DBA
AS CALL ShowSalesOrderDetail( :product_id, :url );
The following is a sample list of acceptable URLs that assign a url value of 101 and a
product_id value of 300:
http://localhost:80/demo/ShowSalesOrderDetail2/101?
product_id=300
http://localhost:80/demo/ShowSalesOrderDetail2?
url=101&product_id=300
http://localhost:80/demo/ShowSalesOrderDetail2?
product_id=300&url=101
When a host variable name is assigned more than once in the context of path-name and url-
query, the last assignment always takes precedence. For example, the following sample URLs
assign a url value of 101 and a product_id value of 300:
http://localhost:80/demo/ShowSalesOrderDetail2/302?
url=101&product_id=300
http://localhost:80/demo/ShowSalesOrderDetail2/String?
product_id=300&url=101
Programming 657
HTTP Web Services
Example
The following URL syntax is used to access a web service named gallery_image that is
running in a database named demo on a local HTTP server through the default port, assuming
that the gallery_image service is defined with URL ON:
http://localhost/demo/gallery_image/sunset.jpg
The URL appears to request a graphic file in a directory from a traditional web server, but it
accesses the gallery_image service with sunset.jpg specified as an input parameter
for an HTTP web server.
The following SQL statement illustrates how the gallery service could be defined on the HTTP
server to accomplish this behavior:
CREATE SERVICE gallery_image
TYPE 'RAW'
URL ON
AUTHORIZATION OFF
USER DBA
AS CALL gallery_image ( :url );
The gallery_image service calls a procedure with the same name, passing the client-
supplied URL. For a sample implementation of a gallery_image procedure that can be
accessed by this web service definitions, see %ALLUSERSPROFILE%\SybaseIQ
\samples\SQLAnywhere\HTTP\gallery.sql.
Perform the following tasks to create an SAP Sybase IQ web client application:
1. Run the following command to create an SAP Sybase IQ client database if one does not
already exist:
iqinit -dba DBA,sql client-database-name
&f=3.1400001049041748&i=9&s=s%20varchar&x=x%20varchar
The web service SampleHTMLService running on the web server extracts the parameter
values for i, f, and s from the POST request and passes them as parameters to the sp_echo
procedure. Parameter value x is ignored. The sp_echo procedure creates a result set which is
Programming 659
HTTP Web Services
returned to the web service. Agreement in parameter names between the client and the web
server is essential for proper mapping.
The web service creates the response which is sent back to the client. The output displayed in
Interactive SQL should be similar to the following output:
Attribute Value
Status HTTP/1.1 200 OK
Body <html>
<head>
<title>/SampleHTMLService</ti-
tle></head>
<body>
<h3>/SampleHTMLService</h3>
<table border=1>
<tr class="head-
er"><th><b>ret_i</b></th>
<th><b>ret_f</b></th>
<th><b>ret_s</b></th>
</tr>
<tr><td>9</
td><td>3.1400001049041748</
td><td>s varchar</td>
Perform the following tasks to access an XML web service using C# or Python:
1. Create a procedure that connects to a web service on an HTTP server.
Write code that accesses the SampleXMLService web service.
• For C#, use the following code:
using System;
using System.Xml;
Console.WriteLine(reader.GetAttribute("ret_f"));
}
break;
}
}
reader.Close();
}
}
Programming 661
HTTP Web Services
parser = xml.sax.make_parser()
parser.setContentHandler( DocHandler() )
parser.parse('http://localhost:8082/SampleXMLService?
i=5&f=3.14&s=hello')
The database name is only required if the HTTP server hosts more than one database. You can
substitute localhost with the host name or the IP address of the HTTP server.
Programming 663
HTTP Web Services
The CERTIFICATE clause in this example indicates that the RSA server certificate is located
in the %ALLUSERSPROFILE%\SybaseIQ\samples\Certificates
\rsaroot.crt file.
Note: Specifying HTTPS_FIPS forces the system to use the FIPS libraries. If HTTPS_FIPS is
specified, but no FIPS libraries are present, non-FIPS libraries are used instead.
In this example, requests are formatted as HTTP:POST requests, which would produce a
request similar to the following:
POST /dbname/SampleWebService HTTP/1.0
ASA-Id: e88a416e24154682bf81694feaf03052
User-Agent: SQLAnywhere/16.0.0.3600
Accept-Charset: windows-1252, UTF-8, *
Date: Fri, 03 Feb 2012 15:02:49 GMT
Host: localhost:8082
Connection: close
Content-Type: application/x-www-form-urlencoded;
charset=windows-1252
Content-Length: 12
a=123&b=data
For example, execute the following statement in the web client database to create a SOAP
procedure named SoapOperation that sends SOAP requests to the specified URL:
CREATE PROCEDURE SoapOperation(intVariable INTEGER, charVariable
CHAR(128))
URL 'HTTP://localhost:8082/dbname/SampleSoapService'
TYPE 'SOAP:DOC';
In this example, a SOAP:DOC request is sent to the URL when you call this procedure, which
would produce a request similar to the following:
POST /dbname/SampleSoapService HTTP/1.0
ASA-Id: e88a416e24154682bf81694feaf03052
User-Agent: SQLAnywhere/16.0.0.3600
Accept-Charset: windows-1252, UTF-8, *
Date: Fri, 03 Feb 2012 15:05:13 GMT
Host: localhost:8082
Connection: close
Content-Type: text/xml; charset=windows-1252
Content-Length: 428
SOAPAction: "HTTP://localhost:8082/SoapOperation"
<?xml version="1.0"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="HTTP://localhost:8082">
<SOAP-ENV:Body>
<m:SoapOperation>
<m:intVariable>123</m:intVariable>
<m:charVariable>data</m:charVariable>
</m:SoapOperation>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The procedure name appears in the <m:SoapOperation> tag within the body. The two
parameters to the procedure, intVariable and charVariable, become
<m:intVariable> and <m:charVariable>, respectively.
By default, the stored procedure name is used as the SOAP operation name when building a
SOAP request. Parameter names appear in SOAP envelope tagnames. You must reference
these names correctly when defining a SOAP stored procedure since the server expects these
names in the SOAP request. The SET clause can be used to specify an alternate SOAP
operation name for the given procedure. WSDLC can be used to read a WSDL from a file or
URL specification and generate SQL stub functions or procedures. For all but the simplest
cases (for example, a SOAP RPC call returning a single string value), it is recommended that
function definitions be used rather than procedures. A SOAP function returns the full SOAP
response envelope which can be parsed using OPENXML.
Programming 665
HTTP Web Services
It is recommended that you specify a range of port numbers when required. Only one
connection is maintained at a time when you specify a single port number; the client
application attempts to access all specified port numbers until it finds one to bind to. After
closing the connection, a timeout period of several minutes is initiated so that no new
connection can be made to the same server and port.
This feature is similar to setting the ClientPort network protocol option.
In this example, the Date header, which is automatically generated by SAP Sybase IQ, is
suppressed. The From header is included but is not assigned a value. A new header named
CustomAlias is included in the HTTP request and is assigned the value of John Doe. The
GET request looks similar to the following:
GET /dbname/SampleWebService HTTP/1.0
ASA-Id: e88a416e24154682bf81694feaf03052
User-Agent: SybaseIQ/16.0.0.3600
Accept-Charset: windows-1252, UTF-8, *
From:
Host: localhost:8082
Connection: close
CustomAlias: John Doe
Folding of long header values is supported, provided that one or more white spaces
immediately follow the \n.
The following example illustrates long header value support:
CREATE PROCEDURE SomeOperation3()
URL 'HTTP://localhost:8082/dbname/SampleWebService'
TYPE 'HTTP:POST'
HEADER 'heading1: This long value\n is really long for a header.
\n
heading2:shortvalue';
Note: You must set the SOAPAction HTTP request header to the given SOAP service URI
as specified in the WSDL when creating a SOAP function or procedure.
Programming 667
HTTP Web Services
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="HTTP://localhost:8082">
<SOAP-ENV:Header>
<Authentication xmlns="CustomerOrderURN">
<userName pwd="none" mustUnderstand="1">
<first>John</first>
<last>Smith</last>
</userName>
</Authentication>
<Session xmlns="SomeSession">123456789</Session>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<m:SoapOperation>
<m:intVariable>123</m:intVariable>
<m:charVariable>data</m:charVariable>
</m:SoapOperation>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Processing SOAP response headers (returned by the SOAP call) differs for functions and
procedures. When using a function, which is the most flexible and recommended approach,
the entire SOAP response envelope is received. The response envelope can then be processed
using the OPENXML operator to extract SOAP header and SOAP body data. When using a
procedure, SOAP response headers can only be extracted through the use of a substitution
parameter that maps to an IN or INOUT variable. A SOAP procedure allows for a maximum of
one IN or INOUT parameter.
A web service function must parse the response SOAP envelope to obtain the header entries.
Examples
The following examples illustrate how to create SOAP procedures and functions that send
parameters and SOAP headers. Wrapper procedures are used to populate the web service
procedure calls and process the responses. The soapAddItemProc procedure illustrates
the use of a SOAP web service procedure, the soapAddItemFunc function illustrates the
use of a SOAP web service function, and the httpAddItemFunc function illustrates how a
SOAP payload may be passed to an HTTP web service procedure.
The following example illustrates a SOAP client procedure that uses substitution parameters
to send SOAP headers. A single INOUT parameter is used to receive SOAP headers. A
wrapper stored procedure addItemProcWrapper that calls soapAddItemProc
demonstrates how to send and receive soap headers including parameters.
CREATE PROCEDURE soapAddItemProc(amount INT, item LONG VARCHAR,
INOUT inoutheader LONG VARCHAR, IN inheader LONG VARCHAR)
URL 'http://localhost:8082/itemStore'
SET 'SOAP( OP=addItems )'
TYPE 'SOAP:DOC'
SOAPHEADER '!inoutheader!inheader';
Programming 669
HTTP Web Services
BEGIN
DECLARE io_header LONG VARCHAR; // inout (write/read) soap
header
DECLARE resxml LONG VARCHAR;
DECLARE soap_header_sent LONG VARCHAR;
DECLARE i_header LONG VARCHAR; // in (write) only soap header
DECLARE err int;
DECLARE crsr CURSOR FOR
CALL soapAddItemProc( amount, item, io_header, i_header );
The following example illustrates a SOAP client function that uses substitution parameters to
send SOAP headers. An entire SOAP response envelope is returned. SOAP headers can be
parsed using the OPENXML operator. A wrapper function addItemFuncWrapper that
calls soapAddItemFunc demonstrates how to send and receive soap headers including
parameters. It also shows how to process the response using the OPENXML operator.
CREATE FUNCTION soapAddItemFunc(amount INT, item LONG VARCHAR,
IN inheader1 LONG VARCHAR, IN inheader2 LONG VARCHAR )
RETURNS XML
URL 'http://localhost:8082/itemStore'
SET 'SOAP(OP=addItems)'
TYPE 'SOAP:DOC'
SOAPHEADER '!inheader1!inheader2';
// Process headers...
SET xpath = '//SOAP-ENV:Header/*';
BEGIN
DECLARE crsr CURSOR FOR SELECT * FROM
OPENXML( res, xpath, 1, ns )
WITH ( "header_entry" LONG VARCHAR '@mp:xmltext',
"localname" LONG VARCHAR
'@mp:localname',
"namespaceuri" LONG VARCHAR
'@mp:namespaceuri' );
OPEN crsr;
FETCH crsr INTO "header_entry", "localname", "namespaceuri";
CLOSE crsr;
END;
// Process body...
SET xpath = '//tns:row';
BEGIN
DECLARE crsr1 CURSOR FOR SELECT * FROM
OPENXML( res, xpath, 1, ns )
WITH ( "r_quantity" INT 'tns:quantity/text()',
"r_item" LONG VARCHAR 'tns:item/
text()',
"r_status" LONG VARCHAR 'tns:status/
text()' );
OPEN crsr1;
FETCH crsr1 INTO "r_quantity", "r_item", "r_status";
CLOSE crsr1;
END;
Programming 671
HTTP Web Services
END;
The following example demonstrates how an HTTP:POST can be used as a transport for an
entire SOAP payload. Rather than creating a webservice client SOAP procedure, this
approach creates a webservice HTTP procedure that transports the SOAP payload. A wrapper
procedure addItemHttpWrapper calls httpAddItemFunc to demonstrate the use of
the POST function. It shows how to send and receive soap headers including parameters and
how to accept the response.
CREATE FUNCTION httpAddItemFunc(soapPayload XML)
RETURNS XML
URL 'http://localhost:8082/itemStore'
TYPE 'HTTP:POST:text/xml'
HEADER 'SOAPAction: "http://localhost:8082/addItems"';
SET payload =
'<?xml version="1.0"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="http://localhost:8082">
<SOAP-ENV:Body>
<m:addItems>
<m:amount>' || amount || '</m:amount>
<m:item>' || item || '</m:item>
</m:addItems>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>';
Limitations
Server side SOAP services cannot currently define input and output SOAP header
requirements. Therefore SOAP header metadata is not available in the WSDL output of a
DISH service. A SOAP client toolkit cannot automatically generate SOAP header
interfaces for an SAP Sybase IQ SOAP service endpoint.
<?xml version="1.0"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
Programming 673
HTTP Web Services
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="http://wsdl.domain.com/">
<SOAP-ENV:Body>
<m:an_operation>
<m:a_parameter>a_value</m:a_parameter>
</m:an_operation>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The namespace for the prefix 'm' is set to http://wsdl.domain.com/ and the
SOAPAction HTTP header specifies a fully qualified URL for the SOAP operation.
The trailing slash is not a requirement for correct operation of SAP Sybase IQ but it can cause a
response failure that is difficult to diagnose. The SOAPAction HTTP header is correctly
generated regardless of the trailing slash.
When a NAMESPACE is not specified, the domain component from the URL clause is used as
the namespace for the SOAP body, and if the procedure is of TYPE 'SOAP:DOC', it is used to
generate the HTTP SOAPAction HTTP header. If in the above example the NAMESPACE
clause is omitted, then http://wsdl.domain.com is used as the namespace. The subtle
difference is that a trailing slash '/' is not present. Every other aspect of the SOAP request,
including the SOAPAction HTTP header would be identical to the above example.
The NAMESPACE clause is used to specify the namespace for the SOAP body as described
for the SOAP:DOC case above. However, the SOAPAction HTTP header is generated with
an empty value: SOAPAction: ""
When using the SOAP:DOC request type, the namespace is also used to compose the
SOAPAction HTTP header.
Variables can be supplied to the SOAP service type by including them as part of a standard
SOAP envelope.
The web server interpretation of the URL depends on how the web service URL clause is
specified.
Programming 675
HTTP Web Services
The statement creates a procedure that allows you to send a variable in the body of an HTTP
request in text/xml format.
Execute the following SQL statement in Interactive SQL to send an HTTP request to the
XMLService web service:
CALL SendXMLContent('<title>Hello World!</title>');
The procedure call assigns a value to the xmlcode parameter and sends it to web service.
In this example, the addItems is the SOAP operation that contains the amount and item
values, which are passed as parameters to the soapAddItemFunc function.
You can send a request by running the following sample script:
SELECT soapAddItemFunc(5, 'shirt');
A call to the soapAddItemFunc function call generates a SOAP envelope that looks
similar to the following:
<?xml version="1.0"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="http://localhost:8082">
<SOAP-ENV:Body>
<m:addItems>
<m:amount>5</m:amount>
<m:item>shirt</m:item>
</m:addItems>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
As an alternative to the previous approach, you can create your own SOAP payload and send it
to the server in an HTTP wrapper.
Variables to SOAP services must be included as part of a standard SOAP request. Values
supplied using other methods are ignored.
The following code illustrates how to create an HTTP wrapper procedure that builds a
customized SOAP envelope:
CREATE PROCEDURE addItemHttpWrapper(amount INT, item LONG VARCHAR)
RESULT(response XML)
BEGIN
DECLARE payload XML;
DECLARE response XML;
SET payload =
'<?xml version="1.0"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="http://localhost:8082">
<SOAP-ENV:Body>
<m:addItems>
<m:amount>' || amount || '</m:amount>
<m:item>' || item || '</m:item>
</m:addItems>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>';
The following code illustrates the web client function used to send the request:
CREATE FUNCTION httpAddItemFunc(soapPayload XML)
RETURNS XML
URL 'http://localhost:8082/itemStore'
TYPE 'HTTP:POST:text/xml'
HEADER 'SOAPAction: "http://localhost:8082/addItems"';
SOAP procedures
The response from a SOAP function is an XML document that contains the SOAP response.
SOAP responses are structured XML documents, so SAP Sybase IQ, by default, attempts to
exploit this information and construct a more useful result set. Each of the top-level tags within
Programming 677
HTTP Web Services
the returned response document is extracted and used as a column name. The contents below
each of these tags in the subtree is used as the row value for that column.
For example, SAP Sybase IQ would construct the shown data set given the following SOAP
response:
<SOAP-ENV:Envelope
xmlns:SOAPSDK1="http://www.w3.org/2001/XMLSchema"
xmlns:SOAPSDK2="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAPSDK3="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<ElizaResponse xmlns:SOAPSDK4="SoapInterop">
<Eliza>Hi, I'm Eliza. Nice to meet you.</Eliza>
<ElizaResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Eliza
Hi, I'm Eliza. Nice to meet you.
In this example, the response document is delimited by the <ElizaResponse> tags that appear
within the <SOAP-ENV:Body> tags.
Result sets have as many columns as there are top-level tags. This result set only has one
column because there is only one top-level tag in the SOAP response. This single top-level tag,
Eliza, becomes the name of the column.
The following web client function, which must be created in a second SAP Sybase IQ
database, issues a call to this web service. The return value of this function is the entire SOAP
response document. The response is in the .NET DataSet format because DNET is the
default SOAP service format.
CREATE FUNCTION get_webservices()
RETURNS LONG VARCHAR
URL 'HTTP://localhost/get_webservices'
TYPE 'SOAP:DOC';
The following statement illustrates how you can use the OPENXML procedure to extract two
columns of the result set. The service_name and secure_required columns indicate
which SOAP services are secure and where HTTPS is required.
SELECT *
FROM OPENXML( get_webservices(), '//row' )
WITH ("Name" CHAR(128) 'service_name',
"Secure?" CHAR(1) 'secure_required' );
This statement works by selecting the decedents of the row node. The WITH clause
constructs the result set based on the two elements of interest. Assuming only the
get_webservices web service exists, this function returns the following result set:
Name Secure?
get_webservices N
Attribute Value
Status HTTP /1.0 200 OK
Body <!DOCTYPE HTML ... ><HTML> ... </HTML>
Content-Type text/html
Server GWS/2.1
Content-Length 2234
Date Mon, 18 Oct 2004, 16:00:00 GMT
Execute the following SELECT query to obtain the response from the web service as a result
set.
SELECT * FROM SybaseWebPage()
WITH (Attribute LONG VARCHAR, Value LONG VARCHAR);
Programming 679
HTTP Web Services
Because the web service procedure does not describe the shape of the result set, the WITH
clause is required to define a temporary view.
The results of a query can be stored in a table. Execute the following SQL statement to create a
table to contain the values of the result set.
CREATE TABLE StoredResults(
Attribute LONG VARCHAR,
Value LONG VARCHAR
);
The result set can be inserted into the StoredResults table as follows:
INSERT INTO StoredResults
SELECT * FROM SybaseWebPage()
WITH (Attribute LONG VARCHAR, Value LONG VARCHAR);
You can add clauses according to the usual syntax of the SELECT statement. For example, if
you want only a specific row of the result set you can add a WHERE clause to limit the results
of the SELECT to only one row.
SELECT * FROM SybaseWebPage()
WITH (Attribute LONG VARCHAR, Value LONG VARCHAR)
WHERE Attribute = 'Status';
This SELECT statement retrieves only the status information from the result set. It can be used
to verify that the call was successful.
In this example, data type information is requested for result set responses only since this
service does not have parameters.
Data typing is applicable to all SAP Sybase IQ web services defined as type 'SOAP'.
The String parameter may be nillable, that is, it may or may not occur.
For a typed parameter such as an integer, the parameter must occur and is not nillable. The
following is an example.
<s:element minOccurs="1" maxOccurs="1" name="an_int"
nillable="false" type="s:int" />
Programming 681
HTTP Web Services
</tns:test_types_concrete_onResponse>
</SOAP-ENV:Body>
The following is an example of a response from a SOAP FORMAT 'XML' web service
returning the XML data as a string. The interior rowset consists of encoded XML and is
presented here in its decoded form for legibility.
<SOAP-ENV:Body>
<tns:test_types_XML_onResponse>
<tns:test_types_XML_onResult xsi:type='xsd:string'>
<tns:rowset
xmlns:tns="http://localhost/satest/dish"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<tns:row>
<tns:lvc xsi:type="xsd:string">Hello World</tns:lvc>
<tns:i xsi:type="xsd:int">99</tns:i>
<tns:ii xsi:type="xsd:long">99999999</tns:ii>
<tns:f xsi:type="xsd:float">3.25</tns:f>
<tns:d xsi:type="xsd:double">.555555555555555582</tns:d>
<tns:bin xsi:type="xsd:base64Binary">AAAAZg==</tns:bin>
<tns:date xsi:type="xsd:date">2006-05-29-04:00</tns:date>
</tns:row>
</tns:rowset>
</tns:test_types_XML_onResult>
<tns:sqlcode>0</tns:sqlcode>
</tns:test_types_XML_onResponse>
</SOAP-ENV:Body>
In addition to the data type information, the namespace for the elements and the XML schema
provides all the information necessary for post processing by an XML parser. When no data
type information exists in the result set (DATATYPE OFF or IN) then the xsi:type and the
XML schema namespace declarations are omitted.
An example of a SOAP FORMAT 'DNET' web service returning a typed SimpleDataSet
follows:
<SOAP-ENV:Body>
<tns:test_types_dnet_outResponse>
<tns:test_types_dnet_outResult
xsi:type='sqlresultstream:SqlRowSet'>
<xsd:schema id='Schema2'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:msdata='urn:schemas-microsoft.com:xml-msdata'>
<xsd:element name='rowset' msdata:IsDataSet='true'>
<xsd:complexType>
<xsd:sequence>
<xsd:element name='row' minOccurs='0' maxOccurs='unbounded'>
<xsd:complexType>
<xsd:sequence>
<xsd:element name='lvc' minOccurs='0' type='xsd:string' />
<xsd:element name='ub' minOccurs='0'
type='xsd:unsignedByte' />
<xsd:element name='s' minOccurs='0' type='xsd:short' />
<xsd:element name='us' minOccurs='0'
type='xsd:unsignedShort' />
<xsd:element name='i' minOccurs='0' type='xsd:int' />
<xsd:element name='ui' minOccurs='0'
type='xsd:unsignedInt' />
<xsd:element name='l' minOccurs='0' type='xsd:long' />
<xsd:element name='ul' minOccurs='0'
type='xsd:unsignedLong' />
<xsd:element name='f' minOccurs='0' type='xsd:float' />
<xsd:element name='d' minOccurs='0' type='xsd:double' />
<xsd:element name='bin' minOccurs='0'
type='xsd:base64Binary' />
<xsd:element name='bool' minOccurs='0'
type='xsd:boolean' />
<xsd:element name='num' minOccurs='0' type='xsd:decimal' />
<xsd:element name='dc' minOccurs='0' type='xsd:decimal' />
<xsd:element name='date' minOccurs='0' type='xsd:date' />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<diffgr:diffgram xmlns:msdata='urn:schemas-microsoft-com:xml-
msdata' xmlns:diffgr='urn:schemas-microsoft-com:xml-diffgram-v1'>
<rowset>
<row>
<lvc>Hello World</lvc>
<ub>128</ub>
<s>-99</s>
<us>33000</us>
<i>-2147483640</i>
<ui>4294967295</ui>
<l>-9223372036854775807</l>
<ul>18446744073709551615</ul>
<f>3.25</f>
<d>.555555555555555582</d>
<bin>QUJD</bin>
<bool>1</bool>
<num>123456.123457</num>
<dc>-1.756000</dc>
<date>2006-05-29-04:00</date>
</row>
</rowset>
</diffgr:diffgram>
</tns:test_types_dnet_outResult>
<tns:sqlcode>0</tns:sqlcode>
</tns:test_types_dnet_outResponse>
</SOAP-ENV:Body>
Programming 683
HTTP Web Services
BIT boolean 1
When one or more parameters are of type NCHAR, NVARCHAR, LONG NVARCHAR, or
NTEXT then the response output is in UTF8. If the client database uses the UTF-8 character
encoding, there is no change in behavior (since NCHAR and CHAR data types are the same).
However, if the database does not use the UTF-8 character encoding, then all parameters that
are not an NCHAR data type are converted to UTF8. The value of the XML declaration
encoding and Content-Type HTTP header will correspond to the character encoding used.
xsd:integer java.math.BigInteger
Programming 685
HTTP Web Services
xsd:long long
xsd:short short
xsd:decimal java.math.BigDecimal
xsd:float float
xsd:double double
xsd:boolean boolean
xsd:byte byte
xsd:QName javax.xml.namespace.QName
xsd:dateTime javax.xml.datatype.XMLGregorianCalendar
xsd:base64Binary byte[]
xsd:hexBinary byte[]
xsd:unsignedInt long
xsd:unsignedShort int
xsd:unsignedByte short
xsd:time javax.xml.datatype.XMLGregorianCalendar
xsd:date javax.xml.datatype.XMLGregorianCalendar
xsd:g javax.xml.datatype.XMLGregorianCalendar
xsd:anySimpleType java.lang.Object
xsd:anySimpleType java.lang.String
xsd:duration javax.xml.datatype.Duration
xsd:NOTATION javax.xml.namespace.QName
The use of web service functions are a better choice when returning complex data such as
arrays or structures. For function declarations, the RETURN clause can specify an XML data
type. The returned XML can be parsed using OPENXML to extract the elements of interest.
A return of XML data such as dateTime is rendered within the result set verbatim. For
example, if a TIMESTAMP column was included within a result set, it would be formatted as
an XML dateTime string (2006-12-25T12:00:00.000-05:00) not as a string (2006-12-25
12:00:00.000).
The XML type demonstrates how to send a parameter as a hexBinary XML type. The SOAP
endpoint expects that the parameter name (or in XML terms, the root element name) is
"inputHexBinary".
Cookbook Constants
Knowledge of how SAP Sybase IQ references namespaces is required to construct complex
structures and arrays. The prefixes listed here correspond to the namespace declarations
generated for an SAP Sybase IQ SOAP request envelope.
SAP Sybase IQ XML Prefix Namespace
xsd http://www.w3.org/2001/XMLSchema
xsi http://www.w3.org/2001/XMLSchema-instance
SOAP-ENC http://schemas.xmlsoap.org/soap/encoding/
Programming 687
HTTP Web Services
The examples are designed to issue requests to the Microsoft SOAP ToolKit 3.0 Round 2
Interoperability test server at http://mssoapinterop.org/stkV3.
All the examples use a table to generate the XML data. The following shows how to set up that
table.
CREATE LOCAL TEMPORARY TABLE SoapData
(
seqno INT DEFAULT AUTOINCREMENT,
i INT,
f FLOAT,
s LONG VARCHAR
) ON COMMIT PRESERVE ROWS;
The following three functions send SOAP requests to the Interoperability server. This sample
issues requests to the Microsoft Interop server:
CREATE FUNCTION echoFloatArray(inputFloatArray XML)
RETURNS XML
URL 'http://mssoapinterop.org/stkV3/Interop.wsdl'
HEADER 'SOAPAction:"http://soapinterop.org/"'
NAMESPACE 'http://soapinterop.org/';
Finally, the three example statements along with the XML representation of their parameters
are presented:
1. The parameters in the following example represent an array.
SELECT echoFloatArray(
XMLELEMENT( 'inputFloatArray',
XMLATTRIBUTES( 'xsd:float[2]' as "SOAP-ENC:arrayType" ),
(
SELECT XMLAGG( XMLELEMENT( 'number', f ) ORDER BY seqno )
FROM SoapData
)
)
);
The stored procedure echoFloatArray will send the following XML to the Interoperability
server.
<inputFloatArray SOAP-ENC:arrayType="xsd:float[2]">
<number>99.9990005493164</number>
<number>199.998992919922</number>
</inputFloatArray>
If the response was stored in a variable, then it can be parsed using OPENXML.
SELECT * FROM OPENXML( resp,'//*:Result/*' )
WITH ( varFloat FLOAT 'text()' );
varFloat
99.9990005493
199.9989929199
2. The parameters in the following example represent a structure.
SELECT echoStruct(
XMLELEMENT('inputStruct',
(
SELECT XMLFOREST( s as varString,
i as varInt,
f as varFloat )
FROM SoapData
WHERE seqno=1
)
)
);
Programming 689
HTTP Web Services
The stored procedure echoStruct will send the following XML to the Interoperability
server.
<inputStruct>
<varString>Ninety-Nine</varString>
<varInt>99</varInt>
<varFloat>99.9990005493164</varFloat>
</inputStruct>
If the response was stored in a variable, then it can be parsed using OPENXML.
SELECT * FROM OPENXML( resp,'//*:Body/*:SOAPStruct' )
WITH (
varString LONG VARCHAR 'varString',
varInt INT 'varInt',
varFloat FLOAT 'varFloat' );
XMLFOREST( s as varString,
i as varInt,
f as varFloat )
)
ORDER BY seqno
)
FROM SoapData
)
)
);
The stored procedure echoFloatArray will send the following XML to the Interoperability
server.
<inputStructArray xmlns:q2="http://soapinterop.org/xsd"
SOAP-ENC:arrayType="q2:SOAPStruct[2]">
<q2:SOAPStruct>
<varString>Ninety-Nine</varString>
<varInt>99</varInt>
<varFloat>99.9990005493164</varFloat>
</q2:SOAPStruct>
<q2:SOAPStruct>
<varString>Hundred and Ninety-Nine</varString>
<varInt>199</varInt>
<varFloat>199.998992919922</varFloat>
</q2:SOAPStruct>
</inputStructArray>
Programming 691
HTTP Web Services
<SOAPSDK7:SOAPStruct
xmlns:SOAPSDK7="http://soapinterop.org/xsd"
id="id2"
SOAPSDK3:root="0"
SOAPSDK2:type="SOAPSDK7:SOAPStruct">
<varString>Hundred and Ninety-Nine</varString>
<varInt>199</varInt>
<varFloat>199.998992919922</varFloat>
</SOAPSDK7:SOAPStruct>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
If the response was stored in a variable, then it can be parsed using OPENXML.
SELECT * FROM OPENXML( resp,'//*:Body/*:SOAPStruct' )
WITH (
varString LONG VARCHAR 'varString',
varInt INT 'varInt',
varFloat FLOAT 'varFloat' );
You can then use the following statement to call the test procedure and initiate an HTTP
request:
CALL test('dba', 'sql', 'NewHeader1:value1\nNewHeader2:value2');
The certificate is read from a file and passed to secure in the following call.
CALL secure( xp_read_file('%ALLUSERSPROFILE%/SybaseIQ/demo\
\Certificates\\rsaroot.crt) );
This example is for illustration only. The certificate can be read directly from a file using the
file= keyword for the CERTIFICATE clause.
In this example, !sizeXL is always deleted because it is a placeholder for which there is no
matching parameter.
Parameters can be used to replace placeholders within the body of the stored function or stored
procedure at the time the function or procedure is called. If placeholders for a particular
variable do not exist, the parameter and its value are passed as part of the request. Parameters
and values used for substitution in this manner are not passed as part of the request.
Programming 693
HTTP Web Services
option settings at the time the function or procedure is invoked. In particular, the conversion
can be affected by such options as precision, scale, and timestamp_format.
If this procedure is invoked with the two values 123 and 'xyz', then the URL used for the
request is equivalent to that shown below:
HTTP://localhost/myservice?a=123&b=xyz
If the type is HTTP:POST, the parameters and their values are URL encoded and placed within
the body of the request. After the headers, the following text appears in the body of the HTTP
request for the two parameter and values:
a=123&b=xyz
Logging is enabled automatically when you specify the -zoc server option. You can enable and
disable logging to this file using the sa_server_option system procedure:
CALL sa_server_option( 'WebClientLogging', 'ON' );
Programming 695
HTTP Web Services
Faults are returned to the client as SOAP faults as defined by the following the SOAP version
1.1 standards when a SOAP service fails:
• When an error in the application handling the request generates a SQLCODE, a SOAP
Fault is returned with a faultcode of Client, possibly with a sub-category, such as
Procedure. The faultstring element within the SOAP Fault is set to a detailed explanation
of the error and a detail element contains the numeric SQLCODE value.
• In the event of a transport protocol error, the faultcode is set to either Client or Server,
depending on the error, faultstring is set to the HTTP transport message, such as 404 Not
Found, and the detail element contains the numeric HTTP error value.
• SOAP Fault messages generated due to application errors that return a SQLCODE value
are returned with an HTTP status of 200 OK.
The appropriate HTTP error is returned in a generated HTML document if the client cannot be
identified as a SOAP client.
Required Software
• SAP Sybase IQ
Programming 697
HTTP Web Services
Goals
• Create and start a new SAP Sybase IQ web server database.
• Create a web service.
• Set up a procedure that returns the information contained in HTTP requests.
• Create and start a new SAP Sybase IQ web client database.
• Send HTTP:POST requests from the web client to the database server.
• Send an HTTP responses from the web server to the web client.
Privileges
The following privileges are required to perform the lessons in this tutorial.
• CREATE ANY OBJECT
• MANAGE ANY WEB SERVICE
Prerequisites
This lesson assumes that you have the roles and privileges listed in the Privileges section at the
start of this tutorial: Tutorial: Create a web server and access it from a web client.
Task
1. Create an SAP Sybase IQ database that will be used to contain web service definitions.
iqinit -dba <user_id>,<password> echo
2. Start a network database server using this database. This server will act as a web server.
iqsrv16 -xs http(port=8082) -n echo echo.db
The HTTP web server is set to listen on port 8082 for requests. Use a different port number
if 8082 is disallowed on your network.
3. Connect to the database server with Interactive SQL.
dbisql -c "UID=<user_id>;PWD=<password>;SERVER=echo"
4. Create a new web service to accept incoming requests.
CREATE SERVICE EchoService
TYPE 'RAW'
USER DBA
AUTHORIZATION OFF
SECURE OFF
AS CALL Echo();
This statement creates a new service named EchoService that calls a stored procedure
named Echo when a web client sends a request to the service. It generates an HTTP
response body without any formatting (RAW) for the web client.
5. Create the Echo procedure to handle incoming requests.
CREATE OR REPLACE PROCEDURE Echo()
BEGIN
DECLARE request_body LONG VARCHAR;
DECLARE request_mimetype LONG VARCHAR;
This procedure formats the Content-Type header and the body of the response that is
sent to the web client.
A web server is set up to receive requests and send responses.
Next
Proceed to Lesson 2: Sending requests from a web client and receiving responses.
Prerequisites
This lesson assumes that you have set up a web server as instructed in Lesson 1.
This lesson assumes that you have the roles and privileges listed in the Privileges section at the
start of this tutorial: Tutorial: Create a web server and access it from a web client.
Task
This lesson contains several references to localhost. Use the host name or IP address of
the web server from Lesson 1 instead of localhost if you are not running the web client on
the same computer as the web server.
Programming 699
HTTP Web Services
1. Create an SAP Sybase IQ database that will be used to contain web client procedures.
iqinit -dba <user_id>,<password> echo_client
2. Start a network database server using this database. This server will act as a web client.
iqsrv16 echo_client.db
3. Connect to the database server with Interactive SQL.
dbisql -c "UID=<user_id>;PWD=<password>;SERVER=echo_client"
4. Create a new stored procedure to send requests to a web service.
CREATE OR REPLACE PROCEDURE SendWithMimeType(
value LONG VARCHAR,
mimeType LONG VARCHAR,
urlSpec LONG VARCHAR
)
URL '!urlSpec'
TYPE 'HTTP:POST:!mimeType';
A web client is set up to send HTTP requests to a web server using the POST method and
receive the web server's response.
Required Software
• SAP Sybase IQ
Goals
• Create and start a new SAP Sybase IQ web server database.
• Create a SOAP web service.
• Set up a procedure that converts a client-supplied Fahrenheit value to a Celsius value.
• Create and start a newSAP Sybase IQ web client database.
• Send a SOAP request from the web client to the database server.
• Send a SOAP response from the database server to the web client.
Privileges
The following privileges are required to perform the lessons in this tutorial.
• CREATE ANY OBJECT
• MANAGE ANY WEB SERVICE
Lesson 1: Setting Up a Web Server to Receive SOAP Requests and Send SOAP
Responses
In this lesson, you set up a new database server and create a SOAP service to handle incoming
SOAP requests. The server anticipates SOAP requests that provide a Fahrenheit temperature
value that is converted to the equivalent Celsius degrees.
Prerequisites
This lesson assumes that you have the roles and privileges listed in the Privileges section at the
start of this tutorial: Tutorial: Using SAP Sybase IQ to access a SOAP/DISH service.
Task
1. Create an SAP Sybase IQ database that will be used to contain web service definitions.
iqinit -dba <user_id>,<password> ftc
Programming 701
HTTP Web Services
2. Start a database server using this database. This server will act as a web server.
iqsrv16 -xs http(port=8082) -n ftc ftc.db
The HTTP web server is set to listen on port 8082 for requests. Use a different port number
if 8082 is disallowed on your network.
3. Connect to the database server with Interactive SQL.
dbisql -c "UID=<user_id>;PWD=<password>;SERVER=ftc"
4. Create a new DISH service to accept incoming requests.
CREATE SERVICE soap_endpoint
TYPE 'DISH'
AUTHORIZATION OFF
SECURE OFF
USER DBA;
This statement creates a new DISH service named soap_endpoint that handles
incoming SOAP service requests.
5. Create a new SOAP service to handle Fahrenheit to Celsius conversions.
CREATE SERVICE FtoCService
TYPE 'SOAP'
FORMAT 'XML'
AUTHORIZATION OFF
USER DBA
AS CALL FToCConverter( :fahrenheit );
This statement creates a new SOAP service named FtoCService that generates XML-
formatted strings as output. It calls a stored procedure named FToCConverter when a
web client sends a SOAP request to the service.
6. Create the FToCConverter procedure to handle incoming SOAP requests. This
procedure performs the necessary calculations to convert a client-supplied Fahrenheit
temperature value to the equivalent Celsius temperature value.
CREATE OR REPLACE PROCEDURE FToCConverter( temperature FLOAT )
BEGIN
DECLARE hd_key LONG VARCHAR;
DECLARE hd_entry LONG VARCHAR;
DECLARE alias LONG VARCHAR;
DECLARE first_name LONG VARCHAR;
DECLARE last_name LONG VARCHAR;
DECLARE xpath LONG VARCHAR;
DECLARE authinfo LONG VARCHAR;
DECLARE namespace LONG VARCHAR;
DECLARE mustUnderstand LONG VARCHAR;
header_loop:
LOOP
SET hd_key = NEXT_SOAP_HEADER( hd_key );
IF hd_key IS NULL THEN
-- no more header entries
LEAVE header_loop;
END IF;
IF hd_key = 'Authentication' THEN
SET hd_entry = SOAP_HEADER( hd_key );
Programming 703
HTTP Web Services
</userName>
</Authentication>
The OPENXML system procedure in the SELECT statement parses the XML header
using the XPath string "/*:Authentication/*:userName" to extract the alias
attribute value and the contents of the first and last tags. The result set is processed
using a cursor to fetch the three column values.
At this point, you have all the information of interest that was passed to the web service.
You have the temperature in Fahrenheit degrees and you have some additional attributes
that were passed to the web service in a SOAP header. You could look up the name and
alias that were provided to see if the person is authorized to use the web service. However,
this exercise is not shown in the example.
The SET statement is used to build a SOAP response in XML format to send to the client.
The following is an XML string representation of a possible SOAP response. It is based on
the above Authentication header structure example.
<Authentication xmlns="SecretAgent" alias="99"
mustUnderstand="1">
<first>Susan</first>
<last>Hilton</last>
</Authentication>
At this point, you now have a running SQL Anywhere web server that provides a service for
converting temperatures from degrees Fahrenheit to degrees Celsius. This service processes a
SOAP header from the client and sends a SOAP response back to the client.
Next
In the next lesson, you develop an example of a client that can send SOAP requests to the web
server and receive SOAP responses from the web server.
Lesson 2: Setting Up a Web Client to Send SOAP Requests and Receive SOAP
Responses
In this lesson, you set up a web client that sends SOAP requests and receives SOAP responses.
Prerequisites
This lesson assumes that you have set up a web server as instructed in the previous lesson.
This lesson assumes that you have the roles and privileges listed in the Privileges section at the
start of this tutorial: Tutorial: Using SAP Sybase IQ to access a SOAP/DISH service.
Task
This lesson contains several references to localhost. Use the host name or IP address of
the web server from lesson 1 instead of localhost if you are not running the web client on
the same computer as the web server.
1. Run the following command to create an SAP Sybase IQdatabase:
iqinit -dba <user_id>,<password> ftc_client
2. Start the database client using the following command:
iqsrv16 ftc_client.db
3. Connect to the database in Interactive SQL using the following command:
dbisql -c "UID=<user_id>;PWD=<password>;SERVER=ftc_client"
4. Create a new stored procedure to send SOAP requests to a DISH service.
Execute the following SQL statement in Interactive SQL:
CREATE OR REPLACE PROCEDURE FtoC( fahrenheit FLOAT,
INOUT inoutheader LONG VARCHAR,
IN inheader LONG VARCHAR )
URL 'http://localhost:8082/soap_endpoint'
SET 'SOAP(OP=FtoCService)'
TYPE 'SOAP:DOC'
SOAPHEADER '!inoutheader!inheader';
Programming 705
HTTP Web Services
The first SET statement creates the XML representation of a SOAP header entry to inform
the web server of user credentials:
<Authentication xmlns="SecretAgent" mustUnderstand="1">
<userName alias="99">
<first>Susan</first>
<last>Hilton</last>
</userName>
</Authentication>
The second SET statement creates the XML representation of a SOAP header entry to
track the client session ID:
<Session xmlns="SomeSession">123456789</Session>
6. The OPEN statement causes the FtoC procedure to be called which sends a SOAP request
to the web server and then processes the response from the web server. The response
includes a header which is returned in inoutheader.
At this point, you now have a client that can send SOAP requests to the web server and receive
SOAP responses from the web server.
Prerequisites
This lesson assumes that you have set up a web server as instructed in lesson 1.
This lesson assumes that you have set up a web client as instructed in lesson 2.
This lesson assumes that you have the roles and privileges listed in the Privileges section at the
start of this tutorial: Tutorial: Using SAP Sybase IQ to access a SOAP/DISH service.
Task
1. Connect to the client database in Interactive SQL if it is not already open from lesson two.
dbisql -c "UID=<user_id>;PWD=<password>;SERVER=ftc_client"
2. Enable logging of SOAP requests and responses.
Execute the following SQL statements in Interactive SQL:
CALL sa_server_option('WebClientLogFile', 'soap.txt');
CALL sa_server_option('WebClientLogging', 'ON');
These calls allow you to examine the content of the SOAP request and response. The
requests and responses are logged to a file called soap.txt.
3. Call the wrapper procedure to send a SOAP request and receive the SOAP response.
Execute the following SQL statement in Interactive SQL:
CALL FahrenheitToCelsius(212);
The FtoC procedure then receives the response from the web server which includes a result set
based on the Fahrenheit value. The SOAP response contains the following.
Programming 707
HTTP Web Services
<SOAP-ENV:Envelope
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'
xmlns:tns='http://localhost:8082'>
<SOAP-ENV:Header>
<Authentication xmlns="SecretAgent" alias="99"
mustUnderstand="1">
<first>Susan</first>
<last>Hilton</last>
</Authentication>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<tns:FtoCServiceResponse>
<tns:FtoCServiceResult xsi:type='xsd:string'>
<tns:rowset xmlns:tns="http://localhost:8082/
ftc">

<tns:row>

<tns:answer>100
</tns:answer>

</tns:row>

</tns:rowset>

</tns:FtoCServiceResult>
<tns:sqlcode>0</tns:sqlcode>
</tns:FtoCServiceResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Required Software
• SAP Sybase IQ
• Visual Studio
Goals
• Create and start a new SAP Sybase IQ web server database.
• Create a SOAP web service.
• Set up a procedure that returns the information contained in a SOAP request.
• Create a DISH web service that provides WSDL documents and acts as a proxy.
• Set up Visual C# on the client computer and import a WSDL document from the web
server.
• Create a Java client application to retrieve information from the SOAP service using the
WSDL document information.
Privileges
The following privileges are required to perform the lessons in this tutorial.
• CREATE ANY OBJECT
• MANAGE ANY WEB SERVICE
Lesson 1: Setting Up a Web Server to Receive SOAP Requests and Send SOAP
Responses
In this lesson, you set up an SAP Sybase IQ web server running SOAP and DISH web services
that handles Visual C# client application requests.
Prerequisites
A recent version of Visual Studio is required.
This lesson assumes that you have the roles and privileges listed in the Privileges section at the
start of this tutorial: Tutorial: Using Visual C# to access a SOAP/DISH web service.
Programming 709
HTTP Web Services
Task
1. Start the SAP Sybase IQ demonstration database using the following command:
iqsrv16 -xs http(port=8082) iqdemo.db
This command indicates that the HTTP web server should listen on port 8082 for requests.
Use a different port number if 8082 is disallowed on your network.
2. Connect to the database server in Interactive SQL using the following command:
dbisql -c "UID=<user_id>;PWD=<password>;SERVER=demo"
3. Create a new SOAP service to accept incoming requests.
Execute the following SQL statement in Interactive SQL:
CREATE SERVICE "SASoapTest/EmployeeList"
TYPE 'SOAP'
DATATYPE ON
AUTHORIZATION OFF
SECURE OFF
USER DBA
AS SELECT * FROM Employees;
DISH web services accessed from .NET should be declared with the FORMAT 'DNET'
clause. The GROUP clause identifies the SOAP services that should be handled by the
DISH service. The EmployeeList service created in the previous step is part of the
GROUP SASoapTest because it is declared as SASoapTest/EmployeeList.
5. Verify that the DISH web service is functional by accessing the associated WSDL
document through a web browser.
You have set up an SAP Sybase IQ web server running SOAP and DISH web services that can
handle Visual C# client application requests.
Next
In the next lesson, you create a Visual C# application to communicate with the web server.
Prerequisites
This lesson assumes that you have set up a web server as instructed in lesson 1.
A recent version of Visual Studio is required to complete this lesson.
This lesson assumes that you have the roles and privileges listed in the Privileges section at the
start of this tutorial: Tutorial: Using Visual C# to access a SOAP/DISH web service.
Task
This lesson contains several references to localhost. Use the host name or IP address of
the web server from lesson 1 instead of localhost if you are not running the web client on
the same computer as the web server.
This example uses functions from the .NET Framework 2.0.
Programming 711
HTTP Web Services
5. Write a procedure that accesses the web reference and uses the available methods.
Double-click the Employee List button and add the following code for the button
click event:
int sqlCode;
listBox1.Items.Clear();
System.Type.GetTypeCode(dr.GetFieldType(i));
switch (typeCode)
{
case System.TypeCode.Int32:
Int32 intValue = dr.GetInt32(i);
listBox1.Items.Add(columnName + "="
+ intValue);
break;
case System.TypeCode.Decimal:
Decimal decValue = dr.GetDecimal(i);
listBox1.Items.Add(columnName + "="
+ decValue.ToString("c"));
break;
case System.TypeCode.String:
string stringValue = dr.GetString(i);
listBox1.Items.Add(columnName + "="
+ stringValue);
break;
case System.TypeCode.DateTime:
DateTime dateValue = dr.GetDateTime(i);
listBox1.Items.Add(columnName + "="
+ dateValue);
break;
case System.TypeCode.Boolean:
Boolean boolValue = dr.GetBoolean(i);
listBox1.Items.Add(columnName + "="
+ boolValue);
break;
case System.TypeCode.DBNull:
listBox1.Items.Add(columnName
+ "=(null)");
break;
default:
listBox1.Items.Add(columnName
+ "=(unsupported)");
break;
}
}
}
listBox1.Items.Add("");
}
dr.Close();
6. Run the application.
Click Debug » Start Debugging.
7. Communicate with the web database server.
Click Employee List.
The ListBox object displays the EmployeeList result set as (type)name=value pairs.
The following output illustrates how an entry appears in the ListBox object:
(Int32)EmployeeID=102
(Int32)ManagerID=501
(String)Surname=Whitney
Programming 713
HTTP Web Services
(String)GivenName=Fran
(Int32)DepartmentID=100
(String)Street=9 East Washington Street
(String)City=Cornwall
(String)State=New York
(String)Country=USA
(String)PostalCode=02192
(String)Phone=6175553985
(String)Status=A
(String)SocialSecurityNumber=017349033
(String)Salary=$45,700.00
(DateTime)StartDate=28/08/1984 0:00:00 AM
(DateTime)TerminationDate=(null)
(DateTime)BirthDate=05/06/1958 0:00:00 AM
(Boolean)BenefitHealthInsurance=True
(Boolean)BenefitLifeInsurance=True
(Boolean)BenefitDayCare=False
(String)Sex=F
The XML response from the web server includes a formatted result set. All column data is
converted to a string representation of the data. The following result set illustrates how result
sets are formatted when they are sent to the client:
<row>
<EmployeeID>102</EmployeeID>
<ManagerID>501</ManagerID>
<Surname>Whitney</Surname>
<GivenName>Fran</GivenName>
<DepartmentID>100</DepartmentID>
<Street>9 East Washington Street</Street>
<City>Cornwall</City>
<State>NY</State>
<Country>USA</Country>
<PostalCode>02192</PostalCode>
<Phone>6175553985</Phone>
<Status>A</Status>
<SocialSecurityNumber>017349033</SocialSecurityNumber>
<Salary>45700.000</Salary>
<StartDate>1984-08-28-05:00</StartDate>
<TerminationDate xsi:nil="true" />
<BirthDate>1958-06-05-05:00</BirthDate>
<BenefitHealthInsurance>1</BenefitHealthInsurance>
<BenefitLifeInsurance>1</BenefitLifeInsurance>
<BenefitDayCare>0</BenefitDayCare>
<Sex>F</Sex>
</row>
Columns containing date or time information include the offset from UTC of the web server.
In the above result set, the offset is -05:00 which is 5 hours to the west of UTC (North
American Eastern Standard Time).
Required Software
• SAP Sybase IQ
• JDK 1.7.0
• JAX-WS 2.2.7 or later version
Programming 715
HTTP Web Services
Goals
• Create and start a new SAP Sybase IQ web server database.
• Create a SOAP web service.
• Set up a procedure that returns the information contained in a SOAP request.
• Create a DISH web service that provides WSDL documents and acts as a proxy.
• Use JAX-WS on the client computer to process a WSDL document from the web server.
• Create a Java client application to retrieve information from the SOAP service using the
WSDL document information.
Privileges
The following privileges are required to perform the lessons in this tutorial.
• CREATE ANY OBJECT
• MANAGE ANY WEB SERVICE
Lesson 1: Setting Up a Web Server to Receive SOAP Requests and Send SOAP
Responses
In this lesson, you set up an SAP Sybase IQ web server running SOAP and DISH web services
that handles JAX-WS client application requests.
Prerequisites
This lesson assumes that you have the roles and privileges listed in the Privileges section at the
start of this tutorial: Tutorial: Using JAX-WS to access a SOAP/DISH web service.
Task
This lesson sets up the web server and a simple web service that you will use in the next lesson.
It can be instructional to use proxy software to observe the XML message traffic. The proxy
inserts itself between your client application and the web server.
1. Start the SAP Sybase IQ demonstration database using the following command:
iqsrv16 -xs http(port=8082) iqdemo.db
This command indicates that the HTTP web server should listen on port 8082 for requests.
Use a different port number if 8082 is disallowed on your network.
2. Connect to the database server with Interactive SQL using the following command:
dbisql -c "UID=<user_id>;PWD=<password>;SERVER=demo"
3. Create a stored procedure that lists Employees table columns.
Execute the following SQL statements in Interactive SQL:
CREATE OR REPLACE PROCEDURE ListEmployees()
RESULT (
EmployeeID INTEGER,
Surname CHAR(20),
GivenName CHAR(20),
StartDate DATE,
TerminationDate DATE )
BEGIN
SELECT EmployeeID, Surname, GivenName, StartDate,
TerminationDate
FROM Employees;
END;
These statements create a new procedure named ListEmployees that defines the
structure of the result set output, and selects certain columns from the Employees table.
4. Create a new SOAP service to accept incoming requests.
Execute the following SQL statement in Interactive SQL:
CREATE SERVICE "WS/EmployeeList"
TYPE 'SOAP'
FORMAT 'CONCRETE' EXPLICIT ON
DATATYPE ON
AUTHORIZATION OFF
SECURE OFF
USER DBA
AS CALL ListEmployees();
This statement creates a new SOAP web service named WS/EmployeeList that
generates a SOAP type as output. It calls the ListEmployees procedure when a web
client sends a request to the service. The service name is surrounded by quotation marks
because of the slash character (/) that appears in the service name.
SOAP web services accessed from JAX-WS should be declared with the FORMAT
'CONCRETE' clause. The EXPLICIT ON clause indicates that the corresponding DISH
service should generate XML Schema that describes an explicit dataset object based on the
result set of the ListEmployees procedure. The EXPLICIT clause only affects the
generated WSDL document.
DATATYPE ON indicates that explicit data type information is generated in the XML
result set response and the input parameters. This option does not affect the WSDL
document that is generated.
5. Create a new DISH service to act as a proxy for the SOAP service and to generate the
WSDL document.
Execute the following SQL statement in Interactive SQL:
Programming 717
HTTP Web Services
DISH web services accessed from JAX-WS should be declared with the FORMAT
'CONCRETE' clause. The GROUP clause identifies the SOAP services that should be
handled by the DISH service. The EmployeeList service created in the previous step is part
of the GROUP WS because it is declared as WS/EmployeeList.
6. Verify that the DISH web service is functional by accessing the associated WSDL
document through a web browser.
Open your web browser and go to http://localhost:8082/demo/WSDish.
The DISH service automatically generates a WSDL document that appears in the browser
window. Examine the EmployeeListDataset object, which looks similar to the
following output:
<s:complexType name="EmployeeListDataset">
<s:sequence>
<s:element name="rowset">
<s:complexType>
<s:sequence>
<s:element name="row" minOccurs="0" maxOccurs="unbounded">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="EmployeeID"
nillable="true" type="s:int" />
<s:element minOccurs="0" maxOccurs="1" name="Surname"
nillable="true" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="GivenName"
nillable="true" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="StartDate"
nillable="true" type="s:date" />
<s:element minOccurs="0" maxOccurs="1" name="TerminationDate"
nillable="true" type="s:date" />
</s:sequence>
</s:complexType>
</s:element>
</s:sequence>
</s:complexType>
</s:element>
</s:sequence>
</s:complexType>
You have set up an SAP Sybase IQ web server running SOAP and DISH web services that can
handle JAX-WS client application requests.
Next
In the next lesson, you create a Java application to communicate with the web server.
Prerequisites
This lesson depends on the steps carried out in lesson 1.
This lesson assumes that you have the roles and privileges listed in the Privileges section at the
start of this tutorial: Tutorial: Using JAX-WS to access a SOAP/DISH web service.
Task
At the time of writing, JAX-WS is included in JDK 1.7.0 and the most recent version of JAX-
WS was 2.2.7. The steps that follow are based on that version. To determine if JAX-WS is
present in your JDK, check for the wsimport application in the JDK bin directory. If it is
not there then go to http://jax-ws.java.net/ to download and install the latest version of JAX-
WS.
This lesson contains several references to localhost. Use the host name or IP address of
the web server from lesson 1 instead of localhost if you are not running the web client on
the same computer as the web server.
1. At a command prompt, create a new working directory for your Java code and generated
files. Change to this new directory.
2. Generate the interface that calls the DISH web service and imports the WSDL document
using the following command:
wsimport -keep "http://localhost:8082/demo/WSDish"
The wsimport application retrieves the WSDL document from the given URL. It
generates .java files to create an interface for it, then compiles them into .class files.
The keep option indicates that the .java files should not be deleted after generating the
class files. The generated Java source code allows you to understand the generated class
files.
The wsimport application creates a new subdirectory structure named localhost
\_8082\demo\ws in your current working directory. The following is a list of the
contents of directory ws:
Programming 719
HTTP Web Services
• EmployeeList.class
• EmployeeList.java
• EmployeeListDataset$Rowset$Row.class
• EmployeeListDataset$Rowset.class
• EmployeeListDataset.class
• EmployeeListDataset.java
• EmployeeListResponse.class
• EmployeeListResponse.java
• FaultMessage.class
• FaultMessage.java
• ObjectFactory.class
• ObjectFactory.java
• package-info.class
• package-info.java
• WSDish.class
• WSDish.java
• WSDishSoapPort.class
• WSDishSoapPort.java
3. Write a Java application that accesses table data from the database server based on the
dataset object schema defined in the generated source code.
The following is a sample Java application that does this. Save the source code as
SASoapDemo.java in the current working directory. Your current working directory
must be the directory containing the localhost subdirectory.
// SASoapDemo.java illustrates a web service client that
// calls the WSDish service and prints out the data.
import java.util.*;
import javax.xml.ws.*;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import javax.xml.datatype.*;
import localhost._8082.demo.ws.*;
Holder<EmployeeListDataset> response =
new Holder<EmployeeListDataset>();
Holder<Integer> sqlcode = new Holder<Integer>();
String fieldType;
String fieldName;
String fieldValue;
Integer fieldInt;
XMLGregorianCalendar fieldDate;
fieldType =
row.getEmployeeID().getDeclaredType().getSimpleName();
fieldName = row.getEmployeeID().getName().getLocalPart();
fieldInt = row.getEmployeeID().getValue();
System.out.println( "(" + fieldType + ")" + fieldName +
"=" + fieldInt );
fieldType =
row.getSurname().getDeclaredType().getSimpleName();
fieldName = row.getSurname().getName().getLocalPart();
fieldValue = row.getSurname().getValue();
System.out.println( "(" + fieldType + ")" + fieldName +
"=" + fieldValue );
fieldType =
row.getGivenName().getDeclaredType().getSimpleName();
fieldName = row.getGivenName().getName().getLocalPart();
fieldValue = row.getGivenName().getValue();
System.out.println( "(" + fieldType + ")" + fieldName +
"=" + fieldValue );
fieldType =
row.getStartDate().getDeclaredType().getSimpleName();
fieldName = row.getStartDate().getName().getLocalPart();
fieldDate = row.getStartDate().getValue();
System.out.println( "(" + fieldType + ")" + fieldName +
"=" + fieldDate );
if ( row.getTerminationDate() == null ) {
fieldType = "unknown";
fieldName = "TerminationDate";
fieldDate = null;
} else {
fieldType =
row.getTerminationDate().getDeclaredType().getSimpleName();
fieldName =
row.getTerminationDate().getName().getLocalPart();
fieldDate = row.getTerminationDate().getValue();
Programming 721
HTTP Web Services
}
System.out.println( "(" + fieldType + ")" + fieldName +
"=" + fieldDate );
System.out.println();
}
}
catch (Exception x) {
x.printStackTrace();
}
}
}
This application prints all server-provided column data to the standard system output.
Note: This application assumes that your SAP Sybase IQ web server is listening on port
8082, as instructed in lesson one. Replace the 8082 portion of the import
localhost._8082.demo.ws.* code line with the port number you specified when
you started the SAP Sybase IQ web server.
For more information about the Java methods used in this application, see the
javax.xml.bind.JAXBElement class API documentation at http://docs.oracle.com/
javase/.
4. Compile your Java application using the following command:
javac SASoapDemo.java
5. Execute the application using the following command:
java SASoapDemo
6. The application sends its request to the web server. It receives an XML result set response
that consists of an EmployeeListResult with a rowset containing several row
entries.
(Integer)EmployeeID=105
(String)Surname=Cobb
(String)GivenName=Matthew
(XMLGregorianCalendar)StartDate=1985-01-01
(unknown)TerminationDate=null
.
.
.
(Integer)EmployeeID=1740
(String)Surname=Nielsen
(String)GivenName=Robert
(XMLGregorianCalendar)StartDate=1994-06-24
(unknown)TerminationDate=null
(Integer)EmployeeID=1751
(String)Surname=Ahmed
(String)GivenName=Alex
(XMLGregorianCalendar)StartDate=1994-07-12
(XMLGregorianCalendar)TerminationDate=2008-04-18
The TerminationDate column is only sent when its value is not NULL. The Java
application is designed to detect when the TerminationDate column is not present. For
this example, the last row in the Employees table was altered such that a non-NULL
termination date was set.
The following is an example of a SOAP response from the web server. The SQLCODE result
from executing the query is included in the response.
<tns:EmployeeListResponse>
<tns:EmployeeListResult xsi:type='tns:EmployeeListDataset'>
<tns:rowset>
<tns:row> ... </tns:row>
.
.
.
<tns:row>
<tns:EmployeeID xsi:type="xsd:int">1751</tns:EmployeeID>
<tns:Surname xsi:type="xsd:string">Ahmed</tns:Surname>
<tns:GivenName xsi:type="xsd:string">Alex</tns:GivenName>
<tns:StartDate xsi:type="xsd:dateTime">1994-07-12</
tns:StartDate>
<tns:TerminationDate xsi:type="xsd:dateTime">2010-03-22</
tns:TerminationDate>
</tns:row>
</tns:rowset>
</tns:EmployeeListResult>
<tns:sqlcode>0</tns:sqlcode>
</tns:EmployeeListResponse>
Programming 723
HTTP Web Services
Programming 725
Three-Tier Computing and Distributed Transactions
Sybase EAServer stores application logic in the form of components, and makes these
components available to client applications. The components may be PowerBuilder®
components, JavaBeans, or COM components.
For more information, see your Sybase EAServer documentation.
Two-Phase Commit
Distributed transactions are managed using two-phase commit. When the work of the
transaction is complete, the transaction manager (DTC) asks all the resource managers
enlisted in the transaction whether they are ready to commit the transaction. This phase is
called preparing to commit.
If all the resource managers respond that they are prepared to commit, DTC sends a commit
request to each resource manager, and responds to its client that the transaction is completed.
If one or more resource manager does not respond, or responds that it cannot commit the
transaction, all the work of the transaction is rolled back across all resource managers.
Programming 727
Three-Tier Computing and Distributed Transactions
In this case, a single resource dispenser is used. The application server asks DTC to prepare a
transaction. DTC and the resource dispenser enlist each connection in the transaction. Each
resource manager must be in contact with both the DTC and the database, so the work can be
performed and the DTC can be notified of its transaction status when required.
A Distributed Transaction Coordinator (DTC) service must be running on each computer to
operate distributed transactions. You can start or stop DTC from the Microsoft Windows
Services window; the DTC service task is named MSDTC.
For more information, see your DTC or EAServer documentation.
Distributed Transactions
While SAP Sybase IQ is enlisted in a distributed transaction, it hands transaction control over
to the transaction server, and SAP Sybase IQ ensures that it does not perform any implicit
transaction management. The following conditions are imposed automatically by SAP Sybase
IQ when it participates in distributed transactions:
• Autocommit is automatically turned off, if it is in use.
• Data definition statements (which commit as a side effect) are disallowed during
distributed transactions.
Programming 729
Three-Tier Computing and Distributed Transactions
Supported Platforms
All the database management utilities use a shared library called the database tools library. It is
supplied for Windows operating systems and for Linux, and Unix. For Windows, the name of
this library is dbtool16.dll. For Linux and Unix, the name of this library is
libdbtool16_r.so.
You can develop your own database management utilities or incorporate database
management features into your applications by calling the database tools library. This section
describes the interface to the database tools library. This section assumes you are familiar with
how to call library routines from the development environment you are using.
The database tools library has functions, or entry points, for each of the database management
utilities. In addition, functions must be called before use of other database tools functions and
when you have finished using other database tools functions.
Programming 731
Database Tools Interface (DBTools)
subdirectory under your SAP Sybase IQ installation directory. You should consult the
dbrmt.h file for the latest information about the DBRemoteSQL entry point and structure
members.
Import libraries
Import libraries for the DBTools interface are provided with SAP Sybase IQ for Windows. For
Windows, they can be found in the SDK\Lib\x86 and SDK\Lib\x64 subdirectories
under your SAP Sybase IQ installation directory. The provided DBTools import libraries are
as follows:
Compiler Library
Microsoft Windows dbtlstm.lib
Callback Functions
Several elements in DBTools structures are of type MSG_CALLBACK. These are pointers to
callback functions.
Programming 733
Database Tools Interface (DBTools)
• Information message – Called for the tools to display some message to the user (such as
the name of the current table being unloaded).
• Status information – Called for the tools to display the status of an operation (such as the
percentage done when unloading a table).
MSG_CALLBACK is defined in the dllapi.h header file supplied with SAP Sybase IQ.
Tools routines can call back to the calling application with messages that should appear in the
appropriate user interface, whether that be a windowing environment, standard output on a
character-based system, or other user interface.
OutputMessageToWindow( messagestr );
}
return( 0 );
}
The version number allows your application to continue working with 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.
When any of the DBTools structures are updated, or when a newer version of the software is
released, the version number is augmented. If you use DB_TOOLS_VERSION_NUMBER
and you rebuild your application with a new version of the DBTools header file, then you must
deploy a new version of the DBTools library.
Bit Fields
Many of the DBTools structures use bit fields to hold Boolean information in a compact
manner. For example, the backup structure includes the following bit fields:
a_bit_field backup_database : 1;
a_bit_field backup_logfile : 1;
a_bit_field no_confirm : 1;
a_bit_field quiet : 1;
Programming 735
Database Tools Interface (DBTools)
a_bit_field rename_log : 1;
a_bit_field truncate_log : 1;
a_bit_field rename_local_log: 1;
a_bit_field server_backup : 1;
Each bit field is one bit long, indicated by the 1 to the right of the colon in the structure
declaration. The specific data type used depends on the value assigned to a_bit_field, which is
set at the top of dbtools.h, and is operating system-dependent.
You assign a value of 0 or 1 to a bit field to pass Boolean information in the structure.
A DBTools Example
You can find this sample and instructions for compiling it in the %ALLUSERSPROFILE%
\SybaseIQ\samples\SQLAnywhere\DBTools directory. The sample program itself
is in main.cpp. The sample illustrates how to use the DBTools library to perform a backup
of a database.
#define WIN32
#include <stdio.h>
#include <string.h>
#include "windows.h"
#include "sqldef.h"
#include "dbtools.h"
extern short _callback ConfirmCallBack( char * str )
{
if( MessageBox( NULL, str, "Backup",
MB_YESNO|MB_ICONQUESTION ) == IDYES )
{
return 1;
}
return 0;
}
extern short _callback MessageCallBack( char * str )
{
if( str != NULL )
{
fprintf( stdout, "%s\n", str );
}
return 0;
}
extern short _callback StatusCallBack( char * str )
{
if( str != NULL )
{
fprintf( stdout, "%s\n", str );
}
return 0;
}
extern short _callback ErrorCallBack( char * str )
{
Programming 737
Database Tools Interface (DBTools)
backup_info.backup_database = 1;
backup_info.backup_logfile = 1;
backup_info.rename_log = 0;
backup_info.truncate_log = 0;
hinst = LoadLibrary( "dbtool16.dll" );
if( hinst == NULL )
{
// Failed
return EXIT_FAIL;
}
dbbackup = (DBTOOLSFUNC) GetProcAddress( (HMODULE)hinst,
"_DBBackup@4" );
dbtoolsinit = (DBTOOLSFUNC) GetProcAddress( (HMODULE)hinst,
"_DBToolsInit@4" );
dbtoolsfini = (DBTOOLSPROC) GetProcAddress( (HMODULE)hinst,
"_DBToolsFini@4" );
ret_code = (*dbtoolsinit)( &dbt_info );
if( ret_code != EXIT_OKAY ) {
return ret_code;
}
ret_code = (*dbbackup)( &backup_info );
(*dbtoolsfini)( &dbt_info );
FreeLibrary( hinst );
return ret_code;
}
Programming 739
Database Tools Interface (DBTools)
Syntax
_crtn short _entry DBBackup(const a_backup_db * pdb)
Parameters
• pdb – Pointer to a properly initialized a_backup_db structure.
Returns
Return code, as listed in Software component exit codes.
Usage
This function is used by the dbbackup utility.
The DBBackup function manages all client-side database backup tasks. For a description of
these tasks, see Backup utility (dbbackup).
To perform a server-side backup, use the BACKUP DATABASE statement.
Syntax
_crtn short _entry DBChangeLogName(const a_change_log * pcl)
Parameters
• pcl – Pointer to a properly initialized a_change_log structure.
Returns
Return code, as listed in Software component exit codes.
Usage
This function is used by the dblog utility.
The -t option of the Transaction Log utility (dblog) changes the name of the transaction log.
DBChangeLogName provides a programmatic interface to this function.
Syntax
_crtn short _entry DBCreate( a_create_db * pcdb)
Parameters
• pcdb – Pointer to a properly initialized a_create_db structure.
Returns
Return code, as listed in Software component exit codes.
Usage
This function is used by the dbinit utility.
Syntax
_crtn short _entry DBCreatedVersion( a_db_version_info * pdvi)
Parameters
• pdvi – Pointer to a properly initialized a_db_version_info structure.
Returns
Return code, as listed in Software component exit codes.
Usage
Currently, this function only differentiates between databases built with version 9 or earlier
and those built with version 10 or later.
Version information is not set if a failing code is returned.
Syntax
_crtn short _entry DBErase(const an_erase_db * pedb)
Programming 741
Database Tools Interface (DBTools)
Parameters
• pedb – Pointer to a properly initialized an_erase_db structure.
Returns
Return code, as listed in Software component exit codes.
Usage
This function is used by the dberase utility.
Syntax
_crtn short _entry DBInfo( a_db_info * pdbi)
Parameters
• pdbi – Pointer to a properly initialized a_db_info structure.
Returns
Return code, as listed in Software component exit codes.
Usage
This function is used by the dbinfo utility.
Syntax
_crtn short _entry DBInfoDump( a_db_info * pdbi)
Parameters
• pdbi – Pointer to a properly initialized a_db_info structure.
Returns
Return code, as listed in Software component exit codes.
Usage
This function is used by the dbinfo utility when the -u option is used.
Syntax
_crtn short _entry DBInfoFree( a_db_info * pdbi)
Parameters
• pdbi – Pointer to a properly initialized a_db_info structure.
Returns
Return code, as listed in Software component exit codes.
Syntax
_crtn short _entry DBLicense(const a_dblic_info * pdi)
Parameters
• pdi – Pointer to a properly initialized a_dblic_info structure.
Returns
Return code, as listed in Software component exit codes.
Syntax
_crtn short _entry DBLogFileInfo(const a_log_file_info * plfi)
Parameters
• plfi – Pointer to a properly initialized a_log_file_info structure.
Returns
Return code, as listed in Software component exit codes.
Programming 743
Database Tools Interface (DBTools)
Usage
Note that this function will only work for databases that have been created with SQL
Anywhere 10.0.0 and up.
Syntax
_crtn short _entry DBRemoteSQL( a_remote_sql * prs)
Parameters
• prs – Pointer to a properly initialized a_remote_sql structure.
Returns
Return code, as listed in Software component exit codes.
Usage
For information about the features you can access, see SQL Remote Message Agent utility
(dbremote).
Syntax
_crtn short _entry DBSynchronizeLog(const a_sync_db * psdb)
Parameters
• psdb – Pointer to a properly initialized a_sync_db structure.
Returns
Return code, as listed in Software component exit codes.
Syntax
_crtn short _entry DBToolsFini(const a_dbtools_info * pdi)
Parameters
• pdi – Pointer to a properly initialized a_dbtools_info structure.
Returns
Return code, as listed in Software component exit codes.
Usage
The DBToolsFini function must be called at the end of any application that uses the DBTools
interface. Failure to do so can lead to lost memory resources.
Syntax
_crtn short _entry DBToolsInit(const a_dbtools_info * pdi)
Parameters
• pdi – Pointer to a properly initialized a_dbtools_info structure.
Returns
Return code, as listed in Software component exit codes.
Usage
The primary purpose of the DBToolsInit function is to load the SQL Anywhere messages
library. The messages library contains localized versions of error messages and prompts used
by the functions in the DBTools library.
The DBToolsInit function must be called at the start of any application that uses the DBTools
interface, before any other DBTools functions.
DBToolsVersion(void) method
Returns the version number of the DBTools library.
Syntax
_crtn short _entry DBToolsVersion(void )
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.
Programming 745
Database Tools Interface (DBTools)
Syntax
_crtn short _entry DBTranslateLog(const a_translate_log * ptl)
Parameters
• ptl – Pointer to a properly initialized a_translate_log structure.
Returns
Return code, as listed in Software component exit codes.
Usage
This function is used by the dbtran utility.
Syntax
_crtn short _entry DBTruncateLog(const a_truncate_log * ptl)
Parameters
• ptl – Pointer to a properly initialized a_truncate_log structure.
Returns
Return code, as listed in Software component exit codes.
Usage
This function is used by the dbbackup utility.
Syntax
_crtn short _entry DBUnload( an_unload_db * pudb)
Parameters
• pudb – Pointer to a properly initialized an_unload_db structure.
Returns
Return code, as listed in Software component exit codes.
Usage
This function is used by the dbunload and dbxtract utilities.
Syntax
_crtn short _entry DBUpgrade(const an_upgrade_db * pudb)
Parameters
• pudb – Pointer to a properly initialized an_upgrade_db structure.
Returns
Return code, as listed in Software component exit codes.
Usage
This function is used by the dbupgrad utility.
Syntax
_crtn short _entry DBValidate(const a_validate_db * pvdb)
Parameters
• pvdb – Pointer to a properly initialized a_validate_db structure.
Returns
Return code, as listed in Software component exit codes.
Usage
This function is used by the dbvalid utility.
Programming 747
Database Tools Interface (DBTools)
Caution: Validating a table or an entire database should be performed while no connections are
making changes to the database; otherwise, spurious errors may be reported indicating some
form of database corruption even though no corruption actually exists.
Autotune() enumeration
Used in the a_backup_db structure to control auto tuning of writers.
Checkpoint() enumeration
Used in the a_backup_db structure to control copying of the checkpoint log.
History() enumeration
Used in the a_backup_db structure to control enabling of backup history.
Padding() enumeration
Blank padding enumeration specifies the blank_pad setting in a_create_db.
Unit() enumeration
Used in the a_create_db structure, to specify the value of db_size_unit.
Unload() enumeration
The type of unload being performed, as used by the an_unload_db structure.
UserList() enumeration
The type of a user list, as used by an a_translate_log structure.
Programming 749
Database Tools Interface (DBTools)
Validation() enumeration
The type of validation being performed, as used by the a_validate_db structure.
Verbosity() enumeration
Verbosity enumeration specifies the volume of output.
Version() enumeration
Used in the a_db_version_info structure, to indicate the version of SQL Anywhere that
initially created the database.
a_backup_db structure
Holds the information needed to perform backup tasks using the DBTools library.
Syntax
typedef struct a_backup_db
auto_tune_writers char
Enable/disable auto tune writers.
Syntax
public char auto_tune_writers;
Remarks
Must be one of BACKUP_AUTO_TUNE_UNSPECIFIED, BACKUP_AUTO_TUNE_ON,
or BACKUP_AUTO_TUNE_OFF. Use to generate AUTO TUNE WRITERS OFF clause. Set
by dbbackup -aw[-] option
Syntax
public const char * backup_comment;
backup_database a_bit_field
Back up the database file.
Syntax
public a_bit_field backup_database;
Remarks
Set TRUE by dbbackup -d option.
backup_history char
Backup history.
Syntax
public char backup_history;
Remarks
Must be one of BACKUP_HISTORY_UNSPECIFIED, BACKUP_HISTORY_ON, or
BACKUP_HISTORY_OFF. Set by dbbackup -h[-] option
Programming 751
Database Tools Interface (DBTools)
backup_interrupted char
Indicates that the operation was interrupted when non-zero.
Syntax
public char backup_interrupted;
backup_logfile a_bit_field
Back up the transaction log file.
Syntax
public a_bit_field backup_logfile;
Remarks
Set TRUE by dbbackup -t option.
chkpt_log_type char
Control copying of checkpoint log.
Syntax
public char chkpt_log_type;
Remarks
Must be one of BACKUP_CHKPT_LOG_COPY, BACKUP_CHKPT_LOG_NOCOPY,
BACKUP_CHKPT_LOG_RECOVER, BACKUP_CHKPT_LOG_AUTO, or
BACKUP_CHKPT_LOG_DEFAULT. Set by dbbackup -k option.
confirmrtn MSG_CALLBACK
Address of a confirmation request callback routine or NULL.
Syntax
public MSG_CALLBACK confirmrtn;
Syntax
public const char * connectparms;
Remarks
They take the form of connection strings, such as the following:
"UID=DBA;PWD=sql;DBF=demo.db".
The database server would be started by the connection string START parameter. For
example: "START=c:\SQLAny16\bin32\dbsrv16.exe".
A full example connection string including the START parameter:
"UID=DBA;PWD=sql;DBF=demo.db;START=c:\SQLAny16\bin32\dbsrv16.exe".
errorrtn MSG_CALLBACK
Address of an error message callback routine or NULL.
Syntax
public MSG_CALLBACK errorrtn;
Syntax
public const char * hotlog_filename;
Remarks
Set by dbbackup -l option.
msgrtn MSG_CALLBACK
Address of an information message callback routine or NULL.
Syntax
public MSG_CALLBACK msgrtn;
no_confirm a_bit_field
Operate without confirmation.
Syntax
public a_bit_field no_confirm;
Remarks
Set TRUE by dbbackup -y option.
Syntax
public const char * output_dir;
Programming 753
Database Tools Interface (DBTools)
page_blocksize a_sql_uint32
Number of pages in data blocks.
Syntax
public a_sql_uint32 page_blocksize;
Remarks
If set to 0, then the default is 128. Set by dbbackup -b option.
progress_messages a_bit_field
Display progress messages.
Syntax
public a_bit_field progress_messages;
Remarks
Set TRUE by dbbackup -p option.
quiet a_bit_field
Operate without printing messages.
Syntax
public a_bit_field quiet;
Remarks
Set TRUE by dbbackup -q option.
rename_local_log a_bit_field
Rename the local backup of the transaction log.
Syntax
public a_bit_field rename_local_log;
Remarks
Set TRUE by dbbackup -n option.
rename_log a_bit_field
Rename the transaction log.
Syntax
public a_bit_field rename_log;
Remarks
Set TRUE by dbbackup -r option.
server_backup a_bit_field
Perform backup on server using BACKUP DATABASE.
Syntax
public a_bit_field server_backup;
Remarks
Set TRUE by dbbackup -s option.
statusrtn MSG_CALLBACK
Address of a status message callback routine or NULL.
Syntax
public MSG_CALLBACK statusrtn;
truncate_log a_bit_field
Delete the transaction log.
Syntax
public a_bit_field truncate_log;
Remarks
Set TRUE by dbbackup -x option.
Syntax
public unsigned short version;
wait_after_end a_bit_field
Wait after end.
Syntax
public a_bit_field wait_after_end;
Remarks
Set TRUE by dbbackup -wa option.
Programming 755
Database Tools Interface (DBTools)
wait_before_start a_bit_field
Wait before start.
Syntax
public a_bit_field wait_before_start;
Remarks
Set TRUE by dbbackup -wb option.
a_change_log structure
Holds the information needed to perform dblog tasks using the DBTools library.
Syntax
typedef struct a_change_log
change_logname a_bit_field
Set TRUE to permit changing of the transaction log name.
Syntax
public a_bit_field change_logname;
Remarks
Set TRUE by dblog -n or -t option.
change_mirrorname a_bit_field
Set TRUE to permit changing of the mirror log name.
Syntax
public a_bit_field change_mirrorname;
Remarks
Set TRUE by dblog -m, -n, or -r option.
Syntax
public const char * dbname;
encryption_key char *
The encryption key for the database file. Equivalent to dblog -ek or -ep option.
Syntax
public char * encryption_key;
errorrtn MSG_CALLBACK
Address of an error message callback routine or NULL.
Syntax
public MSG_CALLBACK errorrtn;
Syntax
public unsigned short generation_number;
ignore_dbsync_trunc a_bit_field
When using dbmlsync, resets the offset kept for the delete_old_logs option, allowing
transaction logs to be deleted when they are no longer needed.
Syntax
public a_bit_field ignore_dbsync_trunc;
Remarks
Set TRUE by dblog -is option.
ignore_ltm_trunc a_bit_field
Reserved, use FALSE.
Syntax
public a_bit_field ignore_ltm_trunc;
ignore_remote_trunc a_bit_field
For SQL Remote.
Syntax
public a_bit_field ignore_remote_trunc;
Remarks
Resets the offset kept for the delete_old_logs option, allowing transaction logs to be deleted
when they are no longer needed. Set TRUE by dblog -ir option.
Programming 757
Database Tools Interface (DBTools)
Syntax
public const char * logname;
Syntax
public const char * mirrorname;
msgrtn MSG_CALLBACK
Address of an information message callback routine or NULL.
Syntax
public MSG_CALLBACK msgrtn;
query_only a_bit_field
If 1, just display the name of the transaction log. If 0, permit changing of the log name.
Syntax
public a_bit_field query_only;
quiet a_bit_field
Operate without printing messages.
Syntax
public a_bit_field quiet;
Remarks
Set TRUE by dblog -q option.
set_generation_number a_bit_field
Reserved. Use FALSE.
Syntax
public a_bit_field set_generation_number;
Syntax
public unsigned short version;
zap_current_offset char *
Change the current offset to the specified value.
Syntax
public char * zap_current_offset;
Remarks
This is for use only in resetting a transaction log after an unload and reload to match dbremote
or dbmlsync settings. Equivalent to dblog -x option.
zap_starting_offset char *
Change the starting offset to the specified value.
Syntax
public char * zap_starting_offset;
Remarks
This is for use only in resetting a transaction log after an unload and reload to match dbremote
or dbmlsync settings. Equivalent to dblog -z option.
a_create_db structure
Holds the information needed to create a database using the DBTools library.
Syntax
typedef struct a_create_db
accent_sensitivity char
One of 'y', 'n', or 'f' (yes, no, French).
Syntax
public char accent_sensitivity;
Remarks
Generates one of the ACCENT RESPECT, ACCENT IGNORE or ACCENT FRENCH
clauses.
Programming 759
Database Tools Interface (DBTools)
avoid_view_collisions a_bit_field
Set TRUE to omit the generation of Watcom SQL compatibility views SYS.SYSCOLUMNS
and SYS.SYSINDEXES.
Syntax
public a_bit_field avoid_view_collisions;
Remarks
Set TRUE by dbinit -k option.
blank_pad a_bit_field
Must be one of NO_BLANK_PADDING or BLANK_PADDING.
Syntax
public a_bit_field blank_pad;
Remarks
Treat blanks as significant in string comparisons and hold index information to reflect this. See
Blank padding enumeration. Equivalent to dbinit -b option.
case_sensitivity_use_default a_bit_field
Set TRUE to use the default case sensitivity for the locale.
Syntax
public a_bit_field case_sensitivity_use_default;
Remarks
This only affects UCA. If set TRUE then we do not add the CASE RESPECT clause to the
CREATE DATABASE statement.
checksum a_bit_field
Set to TRUE for ON or FALSE for OFF.
Syntax
public a_bit_field checksum;
Remarks
Generates one of CHECKSUM ON or CHECKSUM OFF clauses. Set TRUE by dbinit -s
option.
Syntax
public const char * data_store_type;
Syntax
public unsigned int db_size;
db_size_unit int
Used with db_size, must be one of DBSP_UNIT_NONE, DBSP_UNIT_PAGES,
DBSP_UNIT_BYTES, DBSP_UNIT_KILOBYTES, DBSP_UNIT_MEGABYTES,
DBSP_UNIT_GIGABYTES, or DBSP_UNIT_TERABYTES.
Syntax
public int db_size_unit;
Remarks
When not DBSP_UNIT_NONE, it generates the corresponding keyword (for example,
DATABASE SIZE 10 MB is generated when db_size is 10 and db_size_unit is
DBSP_UNIT_MEGABYTES). See Database size unit enumeration.
dba_pwd char *
When not NULL, generates the DBA PASSWORD xxx clause. Equivalent to dbinit -dba
option.
Syntax
public char * dba_pwd;
dba_uid char *
When not NULL, generates the DBA USER xxx clause. Equivalent to dbinit -dba option.
Syntax
public char * dba_uid;
Syntax
public const char * dbname;
Programming 761
Database Tools Interface (DBTools)
Syntax
public const char * default_collation;
Syntax
public const char * encoding;
encrypt a_bit_field
Set TRUE to generate the ENCRYPTED ON clause or, when encrypted_tables is also set, the
ENCRYPTED TABLES ON clause.
Syntax
public a_bit_field encrypt;
Remarks
Set TRUE by dbinit -e? options.
encrypted_tables a_bit_field
Set TRUE to encrypt tables.
Syntax
public a_bit_field encrypted_tables;
Remarks
Used with encrypt, it generates the ENCRYPTED TABLE ON clause instead of the
ENCRYPTED ON clause. Set TRUE by dbinit -et option.
Syntax
public const char * encryption_algorithm;
Remarks
Used with encrypt and encryption_key, it generates the ALGORITHM clause. Equivalent to
dbinit -ea option.
Syntax
public const char * encryption_key;
Remarks
Used with encrypt, it generates the KEY clause. Equivalent to dbinit -ek option.
errorrtn MSG_CALLBACK
Address of an error message callback routine or NULL.
Syntax
public MSG_CALLBACK errorrtn;
iq_params void *
Reserved. Use NULL.
Syntax
public void * iq_params;
jconnect a_bit_field
Set TRUE to include system procedures needed for jConnect.
Syntax
public a_bit_field jconnect;
Remarks
Set FALSE by dbinit -i option.
Syntax
public const char * logname;
Syntax
public const char * mirrorname;
Programming 763
Database Tools Interface (DBTools)
msgrtn MSG_CALLBACK
Address of an information message callback routine or NULL.
Syntax
public MSG_CALLBACK msgrtn;
Syntax
public const char * nchar_collation;
Syntax
public unsigned short page_size;
respect_case a_bit_field
Make string comparisons case sensitive and hold index information to reflect this.
Syntax
public a_bit_field respect_case;
Remarks
Set TRUE by dbinit -c option.
Syntax
public const char * startline;
Remarks
For example: "c:\SQLAny16\bin32\dbsrv16.exe". If NULL, the default START parameter is
"dbeng16 -gp <page_size> -c 10M" for SQL Anywhere where page_size is specified below.
Note that "-c 10M" is appended if page_size >= 2048.
sys_proc_definer a_bit_field
Set TRUE to retain the SQL SECURITY Model for version 12.0.1 or earlier system stored
procedures.
Syntax
public a_bit_field sys_proc_definer;
Remarks
Set TRUE by dbinit -pd option.
verbose char
See Verbosity enumeration (VB_QUIET, VB_NORMAL, VB_VERBOSE).
Syntax
public char verbose;
Syntax
public unsigned short version;
a_db_info structure
Holds the information needed to return DBInfo information using the DBTools library.
Syntax
typedef struct a_db_info
bit_map_pages a_sql_uint32
Number of bitmap pages in the database.
Syntax
public a_sql_uint32 bit_map_pages;
charcollationspecbuffer char *
Pointer to the char collation string buffer.
Syntax
public char * charcollationspecbuffer;
Programming 765
Database Tools Interface (DBTools)
Syntax
public unsigned short charcollationspecbufsize;
charencodingbuffer char *
Pointer to the char encoding string buffer.
Syntax
public char * charencodingbuffer;
Syntax
public unsigned short charencodingbufsize;
checksum a_bit_field
If set TRUE, global checksums are enabled (a checksum on every database page).
Syntax
public a_bit_field checksum;
Syntax
public const char * connectparms;
Remarks
They take the form of connection strings, such as the following:
"UID=DBA;PWD=sql;DBF=demo.db".
The database server would be started by the connection string START parameter. For
example: "START=c:\SQLAny16\bin32\dbsrv16.exe".
A full example connection string including the START parameter:
"UID=DBA;PWD=sql;DBF=demo.db;START=c:\SQLAny16\bin32\dbsrv16.exe".
Syntax
public unsigned short dbbufsize;
dbnamebuffer char *
Pointer to the database file name buffer.
Syntax
public char * dbnamebuffer;
encrypted_tables a_bit_field
If set TRUE, encrypted tables are supported.
Syntax
public a_bit_field encrypted_tables;
errorrtn MSG_CALLBACK
Address of an error message callback routine or NULL.
Syntax
public MSG_CALLBACK errorrtn;
file_size a_sql_uint32
Size of database file (in pages).
Syntax
public a_sql_uint32 file_size;
free_pages a_sql_uint32
Number of free pages.
Syntax
public a_sql_uint32 free_pages;
Syntax
public unsigned short logbufsize;
Programming 767
Database Tools Interface (DBTools)
lognamebuffer char *
Pointer to the transaction log file name buffer.
Syntax
public char * lognamebuffer;
Syntax
public unsigned short mirrorbufsize;
mirrornamebuffer char *
Pointer to the mirror file name buffer.
Syntax
public char * mirrornamebuffer;
msgrtn MSG_CALLBACK
Address of an information message callback routine or NULL.
Syntax
public MSG_CALLBACK msgrtn;
ncharcollationspecbuffer char *
Pointer to the nchar collation string buffer.
Syntax
public char * ncharcollationspecbuffer;
Syntax
public unsigned short ncharcollationspecbufsize;
ncharencodingbuffer char *
Pointer to the nchar encoding string buffer.
Syntax
public char * ncharencodingbuffer;
Syntax
public unsigned short ncharencodingbufsize;
other_pages a_sql_uint32
Number of pages that are not table pages, index pages, free pages, or bitmap pages.
Syntax
public a_sql_uint32 other_pages;
page_usage a_bit_field
Set TRUE to report page usage statistics, otherwise FALSE.
Syntax
public a_bit_field page_usage;
Remarks
Set TRUE by dbinfo -u option.
quiet a_bit_field
Set TRUE to operate without confirming messages.
Syntax
public a_bit_field quiet;
Remarks
Set TRUE by dbinfo -q option.
statusrtn MSG_CALLBACK
Address of a status message callback routine or NULL.
Syntax
public MSG_CALLBACK statusrtn;
sysinfo a_sysinfo
Inline a_sysinfo structure.
Syntax
public a_sysinfo sysinfo;
Programming 769
Database Tools Interface (DBTools)
totals a_table_info *
Pointer to a_table_info structure.
Syntax
public a_table_info * totals;
Syntax
public unsigned short version;
a_db_version_info structure
Holds information regarding which version of SQL Anywhere was used to create the
database.
Syntax
typedef struct a_db_version_info
created_version char
Set to one of VERSION_UNKNOWN, VERSION_PRE_10, etc.
Syntax
public char created_version;
Remarks
indicating the server version that created the database file.
errorrtn MSG_CALLBACK
Address of an error message callback routine or NULL.
Syntax
public MSG_CALLBACK errorrtn;
Syntax
public const char * filename;
msgrtn MSG_CALLBACK
Address of an information message callback routine or NULL.
Syntax
public MSG_CALLBACK msgrtn;
Syntax
public unsigned short version;
a_dblic_info structure
Holds information containing licensing information.
Syntax
typedef struct a_dblic_info
Remarks
You must use this information only in a manner consistent with your license agreement.
compname char *
Company name for licensing.
Syntax
public char * compname;
conncount a_sql_int32
Maximum number of connections licensed.
Syntax
public a_sql_int32 conncount;
Remarks
To set, use 1000000L for default.
errorrtn MSG_CALLBACK
Address of an error message callback routine or NULL.
Syntax
public MSG_CALLBACK errorrtn;
Programming 771
Database Tools Interface (DBTools)
exename char *
Name of the server executable or license file.
Syntax
public char * exename;
installkey char *
Reserved; set NULL.
Syntax
public char * installkey;
Remarks
Set by dblic -k option.
msgrtn MSG_CALLBACK
Address of an information message callback routine or NULL.
Syntax
public MSG_CALLBACK msgrtn;
nodecount a_sql_int32
Number of nodes licensed.
Syntax
public a_sql_int32 nodecount;
query_only a_bit_field
Set TRUE to just display the license information.
Syntax
public a_bit_field query_only;
Remarks
Set FALSE to permit changing the information.
quiet a_bit_field
Set TRUE to operate without printing messages.
Syntax
public a_bit_field quiet;
Remarks
Set TRUE by dblic -q option.
type a_license_type
See lictype.h for values.
Syntax
public a_license_type type;
Remarks
One of LICENSE_TYPE_PERSEAT, LICENSE_TYPE_CONCURRENT, or
LICENSE_TYPE_PERCPU.
username char *
User name for licensing.
Syntax
public char * username;
Syntax
public unsigned short version;
a_dbtools_info structure
DBTools information callback used to initialize and finalize the DBTools library calls.
Syntax
typedef struct a_dbtools_info
errorrtn MSG_CALLBACK
Address of an error message callback routine or NULL.
Syntax
public MSG_CALLBACK errorrtn;
a_log_file_info structure
Used to obtain the log file and mirror log file information of a non-running database.
Syntax
typedef struct a_log_file_info
Programming 773
Database Tools Interface (DBTools)
Syntax
public const char * dbname;
Syntax
public const char * encryption_key;
errorrtn MSG_CALLBACK
Address of an error message callback routine or NULL.
Syntax
public MSG_CALLBACK errorrtn;
logname char *
Buffer for transaction log file name, or NULL.
Syntax
public char * logname;
logname_size size_t
Size of buffer for transaction log file name, or zero.
Syntax
public size_t logname_size;
mirrorname char *
Buffer for mirror log file name, or NULL.
Syntax
public char * mirrorname;
mirrorname_size size_t
Size of buffer for mirror log file name, or zero.
Syntax
public size_t mirrorname_size;
reserved void *
Reserved for internal use and must set to NULL.
Syntax
public void * reserved;
Syntax
public unsigned short version;
a_name structure
Specifies a variable list of names.
Syntax
typedef struct a_name
name char
One or more bytes comprising the name.
Syntax
public char name;
Syntax
public struct a_name * next;
a_remote_sql structure
Holds information needed for the dbremote utility using the DBTools library.
Syntax
typedef struct a_remote_sql
Remarks
The dbremote utility sets the following defaults before processing any command-line options:
• version = DB_TOOLS_VERSION_NUMBER
• argv = (argument vector passed to application)
• deleted = TRUE
Programming 775
Database Tools Interface (DBTools)
• apply = TRUE
• more = TRUE
• link_debug = FALSE
• max_length = 50000
• memory = 2 * 1024 * 1024
• frequency = 1
• threads = 0
• receive_delay = 60
• send_delay = 0
• log_size = 0
• patience_retry = 1
• resend_urgency = 0
• log_file_name = (set from command line)
• truncate_remote_output_file = FALSE
• remote_output_file_name = NULL
• no_user_interaction = TRUE (if user interface is not available)
• errorrtn = (address of an appropriate routine)
• msgrtn = (address of an appropriate routine)
• confirmrtn = (address of an appropriate routine)
• msgqueuertn = (address of an appropriate routine)
• logrtn = (address of an appropriate routine)
• warningrtn = (address of an appropriate routine)
• set_window_title_rtn = (address of an appropriate routine)
• progress_msg_rtn = (address of an appropriate routine)
• progress_index_rtn = (address of an appropriate routine)
apply a_bit_field
Normally set TRUE.
Syntax
public a_bit_field apply;
Remarks
When not set, messages are scanned but not applied. Corresponds to dbremote -a option.
argv char **
Pointer to a parsed command line (a vector of pointers to strings).
Syntax
public char ** argv;
Remarks
If not NULL, then DBRemoteSQL will call a message routine to display each command line
argument except those prefixed with -c, -cq, or -ek.
batch a_bit_field
When set TRUE, force exit after applying message and scanning log (this is the same as at least
one user having 'always' send time).
Syntax
public a_bit_field batch;
Remarks
When cleared, allow run mode to be determined by remote users send times.
confirmrtn MSG_CALLBACK
Address of a confirmation request callback routine or NULL.
Syntax
public MSG_CALLBACK confirmrtn;
connectparms char *
Parameters needed to connect to the database.
Syntax
public char * connectparms;
Remarks
They take the form of connection strings, such as the following:
"UID=DBA;PWD=sql;DBF=demo.db".
The database server would be started by the connection string START parameter. For
example: "START=c:\SQLAny16\bin32\dbeng16.exe".
A full example connection string including the START parameter:
"UID=DBA;PWD=sql;DBF=demo.db;START=c:\SQLAny16\bin32\dbeng16.exe".
debug a_bit_field
When set TRUE, debug output is included.
Syntax
public a_bit_field debug;
Programming 777
Database Tools Interface (DBTools)
debug_dump_size a_sql_uint32
Reserved for internal use and must set to 0.
Syntax
public a_sql_uint32 debug_dump_size;
debug_page_offsets a_bit_field
Reserved for internal use and must set to FALSE.
Syntax
public a_bit_field debug_page_offsets;
default_window_title char *
A pointer to the default window title string.
Syntax
public char * default_window_title;
deleted a_bit_field
Normally set TRUE.
Syntax
public a_bit_field deleted;
Remarks
When not set, messages are not deleted after they are applied. Corresponds to dbremote -p
option.
encryption_key char *
Pointer to an encryption key. Corresponds to the dbremote -ek option.
Syntax
public char * encryption_key;
errorrtn MSG_CALLBACK
Address of an error message callback routine or NULL.
Syntax
public MSG_CALLBACK errorrtn;
frequency a_sql_uint32
Reserved for internal use and must set to 0.
Syntax
public a_sql_uint32 frequency;
full_q_scan a_bit_field
Reserved for internal use and must set to FALSE.
Syntax
public a_bit_field full_q_scan;
include_scan_range char *
Reserved for internal use and must set to NULL.
Syntax
public char * include_scan_range;
latest_backup a_bit_field
When set TRUE, only logs that are backed up are processed.
Syntax
public a_bit_field latest_backup;
Remarks
Don't send operations from a live log. Corresponds to the dbremote -u option.
link_debug a_bit_field
When set TRUE, debugging will be turned on for links.
Syntax
public a_bit_field link_debug;
locale char *
Reserved for internal use and must set to NULL.
Syntax
public char * locale;
Programming 779
Database Tools Interface (DBTools)
Syntax
public const char * log_file_name;
Remarks
If send is TRUE, the error log is sent to the consolidated (unless this pointer is NULL).
log_size a_sql_uint32
DBRemoteSQL renames and restarts the online transaction log when the size of the online
transaction log is greater than this value.
Syntax
public a_sql_uint32 log_size;
Remarks
Corresponds to the dbremote -x option.
logrtn MSG_CALLBACK
Pointer to a function that prints the given message to a log file.
Syntax
public MSG_CALLBACK logrtn;
Remarks
These messages do not need to be seen by the user.
max_length a_sql_uint32
Set to the maximum length (in bytes) a message can have.
Syntax
public a_sql_uint32 max_length;
Remarks
This affects sending and receiving. The recommended value is 50000. Corresponds to the
dbremote -l option.
memory a_sql_uint32
Set to the maximum size (in bytes) of memory buffers to use while building messages to send.
Syntax
public a_sql_uint32 memory;
Remarks
The recommended value is at least 2 * 1024 * 1024. Corresponds to the dbremote -m option.
mirror_logs char *
Pointer to the name of the directory containing offline mirror transaction logs.
Syntax
public char * mirror_logs;
Remarks
Corresponds to the dbremote -ml option.
more a_bit_field
This should be set to TRUE.
Syntax
public a_bit_field more;
msgqueuertn MSG_QUEUE_CALLBACK
Function called by DBRemoteSQL when it wants to sleep.
Syntax
public MSG_QUEUE_CALLBACK msgqueuertn;
Remarks
The parameter specifies the sleep period in milliseconds. The function should return the
following, as defined in dllapi.h.
• MSGQ_SLEEP_THROUGH indicates that the routine slept for the requested number of
milliseconds. This is usually the value you should return.
• MSGQ_SHUTDOWN_REQUESTED indicates that you would like the synchronization
to terminate as soon as possible.
msgrtn MSG_CALLBACK
Address of an information message callback routine or NULL.
Syntax
public MSG_CALLBACK msgrtn;
Programming 781
Database Tools Interface (DBTools)
no_user_interaction a_bit_field
When set TRUE, no user interaction is requested.
Syntax
public a_bit_field no_user_interaction;
operations a_sql_uint32
This value is used when applying messages.
Syntax
public a_sql_uint32 operations;
Remarks
Commits are ignored until DBRemoteSQL has at least this number of operations(inserts,
deletes, updates) that are uncommitted. Corresponds to the dbremote -g option.
patience_retry a_sql_uint32
Set this to the number of polls for incoming messages that DBRemoteSQL should wait before
assuming that a message it is expecting is lost.
Syntax
public a_sql_uint32 patience_retry;
Remarks
For example, if patience_retry is 3 then DBRemoteSQL tries up to three times to receive the
missing message. Afterward, it sends a resend request. The recommended value is 1.
Corresponds to the dbremote -rp option.
progress_index_rtn SET_PROGRESS_CALLBACK
Pointer to a function that updates the state of the progress bar.
Syntax
public SET_PROGRESS_CALLBACK progress_index_rtn;
Remarks
This function takes two unsigned integer arguments index and max. On the first call, the values
are the minimum and maximum values (for example, 0, 100). On subsequent calls, the first
argument is the current index value (for example, between 0 and 100) and the second argument
is always 0.
progress_msg_rtn MSG_CALLBACK
Pointer to a function that displays a progress message.
Syntax
public MSG_CALLBACK progress_msg_rtn;
queueparms char *
Reserved for internal use and must set to NULL.
Syntax
public char * queueparms;
receive a_bit_field
When set TRUE, messages are received.
Syntax
public a_bit_field receive;
Remarks
If receive and send are both FALSE then both are assumed TRUE. It is recommended to set
receive and send FALSE. Corresponds to the dbremote -r option.
receive_delay a_sql_uint32
Set this to the time (in seconds) to wait between polls for new incoming messages.
Syntax
public a_sql_uint32 receive_delay;
Remarks
The recommended value is 60. Corresponds to the dbremote -rd option.
remote_output_file_name char *
Pointer to the name of the DBRemoteSQL remote output file.
Syntax
public char * remote_output_file_name;
Remarks
Corresponds to the dbremote -ro or -rt option.
Programming 783
Database Tools Interface (DBTools)
rename_log a_bit_field
When set TRUE, logs are renamed and restarted (DBRemoteSQL only).
Syntax
public a_bit_field rename_log;
resend_urgency a_sql_uint32
Set the time (in seconds) that DBRemoteSQL waits after seeing that a user needs a rescan
before performing a full scan of the log.
Syntax
public a_sql_uint32 resend_urgency;
Remarks
Set to zero to allow DBRemoteSQL to choose a good value based on user send times and other
information it has collected. Corresponds to the dbremote -ru option.
scan_log a_bit_field
Reserved for internal use and must set to FALSE.
Syntax
public a_bit_field scan_log;
send a_bit_field
When set TRUE, messages are sent.
Syntax
public a_bit_field send;
Remarks
If receive and send are both FALSE then both are assumed TRUE. It is recommended to set
receive and send FALSE. Corresponds to the dbremote -s option.
send_delay a_sql_uint32
Set the time (in seconds) between scans of the log file for new operations to send.
Syntax
public a_sql_uint32 send_delay;
Remarks
Set to zero to allow DBRemoteSQL to choose a good value based on user send times.
Corresponds to the dbremote -sd option.
set_window_title_rtn SET_WINDOW_TITLE_CALLBACK
Pointer to a function that resets the title of the window (Windows only).
Syntax
public SET_WINDOW_TITLE_CALLBACK set_window_title_rtn;
Remarks
The title could be "database_name (receiving, scanning, or sending) - default_window_title".
threads a_sql_uint32
Set the number of worker threads that should be used to apply messages.
Syntax
public a_sql_uint32 threads;
Remarks
This value must not exceed 50. Corresponds to the dbremote -w option.
transaction_logs char *
Should identify the directory with offline transaction logs (DBRemoteSQL only).
Syntax
public char * transaction_logs;
Remarks
Corresponds to the transaction_logs_directory argument of dbremote.
triggers a_bit_field
This should usually be cleared (FALSE) in most cases.
Syntax
public a_bit_field triggers;
Remarks
When set TRUE, trigger actions are replicated. Care should be exercised.
truncate_remote_output_file a_bit_field
When set TRUE, the remote output file is truncated rather than appended to.
Syntax
public a_bit_field truncate_remote_output_file;
Programming 785
Database Tools Interface (DBTools)
Remarks
Corresponds to the dbremote -rt option.
unused a_bit_field
Reserved for internal use and must set to FALSE.
Syntax
public a_bit_field unused;
use_hex_offsets a_bit_field
When set TRUE, log offsets are shown in hexadecimal notation; otherwise decimal notation is
used.
Syntax
public a_bit_field use_hex_offsets;
use_relative_offsets a_bit_field
When set TRUE, log offsets are displayed as relative to the start of the current log file.
Syntax
public a_bit_field use_relative_offsets;
Remarks
When set FALSE, log offsets from the beginning of time are displayed.
verbose a_bit_field
When set, extra information is produced.
Syntax
public a_bit_field verbose;
Remarks
Corresponds to the dbremote -v option.
Syntax
public unsigned short version;
warningrtn MSG_CALLBACK
Pointer to a function that displays the given warning message.
Syntax
public MSG_CALLBACK warningrtn;
Remarks
If NULL, the errorrtn function is called instead.
a_sync_db structure
Holds information needed for the dbmlsync utility using the DBTools library.
Syntax
typedef struct a_sync_db
Remarks
Some members correspond to features accessible from the dbmlsync command line utility.
Unused members should be assigned the value 0, FALSE, or NULL, depending on data type.
allow_outside_connect a_bit_field
Reserved; use 0.
Syntax
public a_bit_field allow_outside_connect;
allow_schema_change a_bit_field
Set TRUE to check for schema changes between synchronizations.
Syntax
public a_bit_field allow_schema_change;
Remarks
Equivalent to the dbmlsync -sc option.
Syntax
public const char * apply_dnld_file;
Remarks
Equivalent to dbmlsync -ba option or NULL if option not specified.
Programming 787
Database Tools Interface (DBTools)
argv char **
The argv array for this run, the last element of the array must be NULL.
Syntax
public char ** argv;
autoclose a_bit_field
Set TRUE to close window on completion.
Syntax
public a_bit_field autoclose;
Remarks
Equivalent to the dbmlsync -qc option.
background_retry a_sql_int32
Number of times to retry an interrupted background synchronization.
Syntax
public a_sql_int32 background_retry;
Remarks
Equivalent to the dbmlsync -bkr option.
background_sync a_bit_field
Set TRUE to do a background synchronization.
Syntax
public a_bit_field background_sync;
Remarks
Equivalent to the dbmlsync -bk option.
cache_verbosity a_bit_field
Reserved; use 0.
Syntax
public a_bit_field cache_verbosity;
ce_argv char **
Reserved; use NULL.
Syntax
public char ** ce_argv;
ce_reproc_argv char **
Reserved; use NULL.
Syntax
public char ** ce_reproc_argv;
changing_pwd a_bit_field
Set TRUE when setting a new MobiLink password.
Syntax
public a_bit_field changing_pwd;
Remarks
See new_mlpassword field. Equivalent to the dbmlsync -mn option.
confirmrtn MSG_CALLBACK
Address of a confirmation request callback routine or NULL.
Syntax
public MSG_CALLBACK confirmrtn;
connectparms char *
Parameters needed to connect to the database.
Syntax
public char * connectparms;
Remarks
They take the form of connection strings, such as the following:
"UID=DBA;PWD=sql;DBF=demo.db".
The database server would be started by the connection string START parameter. For
example: "START=c:\SQLAny16\bin32\dbsrv16.exe".
A full example connection string including the START parameter:
"UID=DBA;PWD=sql;DBF=demo.db;START=c:\SQLAny16\bin32\dbsrv16.exe".
Programming 789
Database Tools Interface (DBTools)
connectparms_allocated a_bit_field
Reserved; use 0.
Syntax
public a_bit_field connectparms_allocated;
continue_download a_bit_field
Set TRUE to continue a previously failed download.
Syntax
public a_bit_field continue_download;
Remarks
Equivalent to the dbmlsync -dc option.
Syntax
public const char * create_dnld_file;
Remarks
Equivalent to dbmlsync -bc option or NULL if option not specified.
debug a_bit_field
Reserved; use 0.
Syntax
public a_bit_field debug;
debug_dump_char a_bit_field
Reserved; use 0.
Syntax
public a_bit_field debug_dump_char;
debug_dump_hex a_bit_field
Reserved; use 0.
Syntax
public a_bit_field debug_dump_hex;
debug_dump_size a_sql_uint32
Reserved; use 0.
Syntax
public a_sql_uint32 debug_dump_size;
debug_page_offsets a_bit_field
Reserved; use 0.
Syntax
public a_bit_field debug_page_offsets;
default_window_title char *
Name of the program to display in the window caption (for example, DBMLSync).
Syntax
public char * default_window_title;
dl_insert_width a_sql_uint32
Reserved; use 0.
Syntax
public a_sql_uint32 dl_insert_width;
dl_use_put a_bit_field
Reserved; use 0.
Syntax
public a_bit_field dl_use_put;
dlg_info_msg a_sql_uint32
Reserved; use 0.
Syntax
public a_sql_uint32 dlg_info_msg;
dnld_fail_len a_sql_uint32
Reserved; use 0.
Syntax
public a_sql_uint32 dnld_fail_len;
Programming 791
Database Tools Interface (DBTools)
Syntax
public const char * dnld_file_extra;
Remarks
Equivalent to dbmlsync -be option.
dnld_gen_num a_bit_field
Set TRUE to update generation number when download file is applied.
Syntax
public a_bit_field dnld_gen_num;
Remarks
Equivalent to the dbmlsync -bg option.
dnld_read_size a_sql_uint32
Set the download read size.
Syntax
public a_sql_uint32 dnld_read_size;
Remarks
Equivalent to the dbmlsync -drs option.
download_only a_bit_field
Set TRUE to perform download-only synchronization.
Syntax
public a_bit_field download_only;
Remarks
Equivalent to the dbmlsync -ds option.
Syntax
public const char * encrypted_stream_opts;
encryption_key char *
The encryption key for the database file.
Syntax
public char * encryption_key;
Remarks
Equivalent to the dbmlsync -ek option.
entered_dialog a_bit_field
Reserved; use 0.
Syntax
public a_bit_field entered_dialog;
errorrtn MSG_CALLBACK
Address of an error message callback routine or NULL.
Syntax
public MSG_CALLBACK errorrtn;
est_upld_row_cnt a_sql_uint32
Set the estimated upload row count (for optimization).
Syntax
public a_sql_uint32 est_upld_row_cnt;
Remarks
Equivalent to the dbmlsync -urc option.
extended_options char *
Extended options in the form "keyword=value;...".
Syntax
public char * extended_options;
Remarks
Equivalent to dbmlsync -e option.
Programming 793
Database Tools Interface (DBTools)
hide_conn_str a_bit_field
Set FALSE to show connect string, TRUE to hide the connect string.
Syntax
public a_bit_field hide_conn_str;
Remarks
Equivalent to the dbmlsync -vc option.
hide_ml_pwd a_bit_field
Set FALSE to show MobiLink password, TRUE to hide the MobiLink password.
Syntax
public a_bit_field hide_ml_pwd;
Remarks
Equivalent to the dbmlsync -vp option.
hovering_frequency a_sql_uint32
Set the logscan polling period in seconds.
Syntax
public a_sql_uint32 hovering_frequency;
Remarks
Usually 60. Equivalent to the dbmlsync -pp option.
ignore_debug_interrupt a_bit_field
Reserved; use 0.
Syntax
public a_bit_field ignore_debug_interrupt;
ignore_hook_errors a_bit_field
Set TRUE to ignore errors that occur in hook functions.
Syntax
public a_bit_field ignore_hook_errors;
Remarks
Equivalent to the dbmlsync -eh option.
ignore_hovering a_bit_field
Set TRUE to disable logscan polling.
Syntax
public a_bit_field ignore_hovering;
Remarks
Equivalent to the dbmlsync -p option.
ignore_scheduling a_bit_field
Set TRUE to ignore scheduling.
Syntax
public a_bit_field ignore_scheduling;
Remarks
Equivalent to the dbmlsync -is option.
Syntax
public const char * include_scan_range;
init_cache a_sql_uint32
Initial size for cache.
Syntax
public a_sql_uint32 init_cache;
Remarks
Equivalent to the dbmlsync -ci option.
init_cache_suffix char
Suffix for initial cache size ('B' for bytes, 'P' for percentage, or 0 if not specified.
Syntax
public char init_cache_suffix;
Programming 795
Database Tools Interface (DBTools)
kill_other_connections a_bit_field
Set TRUE to drop connections with locks on tables being synchronized.
Syntax
public a_bit_field kill_other_connections;
Remarks
Equivalent to the dbmlsync -d option.
last_upload_def a_syncpub *
Reserved; use NULL.
Syntax
public a_syncpub * last_upload_def;
lite_blob_handling a_bit_field
Reserved; use 0.
Syntax
public a_bit_field lite_blob_handling;
Syntax
public const char * log_file_name;
Remarks
Equivalent to dbmlsync -o or -ot option.
log_size a_sql_uint32
Size in bytes of log file when renaming and restarting the transaction log.
Syntax
public a_sql_uint32 log_size;
Remarks
Specify 0 for unspecified size. Equivalent to the dbmlsync -x option.
logrtn MSG_CALLBACK
Address of a logging callback routine to write messages only to a log file or NULL.
Syntax
public MSG_CALLBACK logrtn;
max_cache a_sql_uint32
Maximum size for cache.
Syntax
public a_sql_uint32 max_cache;
Remarks
Equivalent to the dbmlsync -cm option.
max_cache_suffix char
Suffix for maximum cache size ('B' for bytes, 'P' for percentage, or 0 if not specified.
Syntax
public char max_cache_suffix;
min_cache a_sql_uint32
Minimum size for cache.
Syntax
public a_sql_uint32 min_cache;
Remarks
Equivalent to the dbmlsync -cl option.
min_cache_suffix char
Suffix for minimum cache size ('B' for bytes, 'P' for percentage, or 0 if not specified.
Syntax
public char min_cache_suffix;
mlpassword char *
The MobiLink password or NULL, if the option is not specified.
Syntax
public char * mlpassword;
Programming 797
Database Tools Interface (DBTools)
Remarks
Equivalent to the dbmlsync -mp option.
msgqueuertn MSG_QUEUE_CALLBACK
Function called by DBMLSync when it wants to sleep.
Syntax
public MSG_QUEUE_CALLBACK msgqueuertn;
Remarks
The parameter specifies the sleep period in milliseconds. The function should return the
following, as defined in dllapi.h.
• MSGQ_SLEEP_THROUGH indicates that the routine slept for the requested number of
milliseconds. This is usually the value you should return.
• MSGQ_SHUTDOWN_REQUESTED indicates that you would like the synchronization
to terminate as soon as possible.
• MSGQ_SYNC_REQUESTED indicates that the routine slept for less than the requested
number of milliseconds and that the next synchronization should begin immediately if a
synchronization is not currently in progress.
msgrtn MSG_CALLBACK
Address of an information message callback routine or NULL.
Syntax
public MSG_CALLBACK msgrtn;
new_mlpassword char *
The new MobiLink password or NULL, if the option is not specified.
Syntax
public char * new_mlpassword;
Remarks
Equivalent to the dbmlsync -mn option.
no_offline_logscan a_sql_uint32
Set TRUE to disable offline logscan (cannot use with -x).
Syntax
public a_sql_uint32 no_offline_logscan;
Remarks
Equivalent to the dbmlsync -do option.
no_schema_cache a_bit_field
Reserved; use 0.
Syntax
public a_bit_field no_schema_cache;
no_stream_compress a_bit_field
Reserved; use 0.
Syntax
public a_bit_field no_stream_compress;
Syntax
public const char * offline_dir;
Remarks
Last item specified on dbmlsync command line.
output_to_file a_bit_field
Reserved; use 0.
Syntax
public a_bit_field output_to_file;
output_to_mobile_link a_bit_field
Reserved; use 1.
Syntax
public a_bit_field output_to_mobile_link;
persist_connection a_bit_field
Set TRUE to persist the MobiLink connection between synchronizations.
Syntax
public a_bit_field persist_connection;
Remarks
Set FALSE to close the MobiLink connection between synchronizations. Equivalent to the
dbmlsync -pc{+|-} option.
Programming 799
Database Tools Interface (DBTools)
ping a_bit_field
Set TRUE to ping MobiLink server.
Syntax
public a_bit_field ping;
Remarks
Equivalent to the dbmlsync -pi option.
preload_dlls char *
Reserved; use NULL.
Syntax
public char * preload_dlls;
progress_index_rtn SET_PROGRESS_CALLBACK
Function called to update the state of the progress bar.
Syntax
public SET_PROGRESS_CALLBACK progress_index_rtn;
progress_msg_rtn MSG_CALLBACK
Function called to change the text in the status window, above the progress bar.
Syntax
public MSG_CALLBACK progress_msg_rtn;
prompt_again a_bit_field
Reserved; use 0.
Syntax
public a_bit_field prompt_again;
prompt_for_encrypt_key a_bit_field
Reserved; use 0.
Syntax
public a_bit_field prompt_for_encrypt_key;
protocol_add_cli_bit_to_cli_both a_bit_field
Reserved; use 0.
Syntax
public a_bit_field protocol_add_cli_bit_to_cli_both;
protocol_add_cli_bit_to_cli_max a_bit_field
Reserved; use 0.
Syntax
public a_bit_field protocol_add_cli_bit_to_cli_max;
protocol_add_serv_bit_to_cli_both a_bit_field
Reserved; use 0.
Syntax
public a_bit_field protocol_add_serv_bit_to_cli_both;
protocol_add_serv_bit_to_cli_max a_bit_field
Reserved; use 0.
Syntax
public a_bit_field protocol_add_serv_bit_to_cli_max;
protocol_add_serv_bit_to_serv_both a_bit_field
Reserved; use 0.
Syntax
public a_bit_field protocol_add_serv_bit_to_serv_both;
protocol_add_serv_bit_to_serv_max a_bit_field
Reserved; use 0.
Syntax
public a_bit_field protocol_add_serv_bit_to_serv_max;
Syntax
public const char * raw_file;
Programming 801
Database Tools Interface (DBTools)
rename_log a_bit_field
Set TRUE to rename and restart the transaction log.
Syntax
public a_bit_field rename_log;
Remarks
See log_size field. Equivalent to the dbmlsync -x option.
reserved a_bit_field
Reserved; use 0.
Syntax
public a_bit_field reserved;
retry_remote_ahead a_bit_field
Set TRUE to resend upload using remote offset on progress mismatch when remote offset is
greater than consolidated offset.
Syntax
public a_bit_field retry_remote_ahead;
Remarks
Equivalent to the dbmlsync -ra option.
retry_remote_behind a_bit_field
Set TRUE to resend upload using remote offset on progress mismatch.
Syntax
public a_bit_field retry_remote_behind;
Remarks
when remote offset is less than consolidated offset. Equivalent to the dbmlsync -r or -rb option.
server_mode a_bit_field
Set TRUE to run in server mode.
Syntax
public a_bit_field server_mode;
Remarks
Equivalent to the dbmlsync -sm option.
server_port a_sql_uint32
Set communication port when running in server mode.
Syntax
public a_sql_uint32 server_port;
Remarks
Equivalent to the dbmlsync -po option.
set_window_title_rtn SET_WINDOW_TITLE_CALLBACK
Function to call to change the title of the dbmlsync window (Windows only).
Syntax
public SET_WINDOW_TITLE_CALLBACK set_window_title_rtn;
status_rtn STATUS_CALLBACK
Reserved; use NULL.
Syntax
public STATUS_CALLBACK status_rtn;
strictly_free_memory a_bit_field
Reserved; use 0.
Syntax
public a_bit_field strictly_free_memory;
strictly_ignore_trigger_ops a_bit_field
Reserved; use 0.
Syntax
public a_bit_field strictly_ignore_trigger_ops;
sync_opt char *
Reserved; use NULL.
Syntax
public char * sync_opt;
Programming 803
Database Tools Interface (DBTools)
sync_params char *
User authentication parameters.
Syntax
public char * sync_params;
Remarks
Equivalent to the dbmlsync -ap option.
sync_profile char *
Synchronization profile to execute.
Syntax
public char * sync_profile;
Remarks
Equivalent to the dbmlsync -sp option.
trans_upload a_bit_field
Set TRUE to upload each database transaction separately.
Syntax
public a_bit_field trans_upload;
Remarks
Equivalent to the dbmlsync -tu option.
upld_fail_len a_sql_uint32
Reserved; use 0.
Syntax
public a_sql_uint32 upld_fail_len;
upload_defs a_syncpub *
Linked list of publications/subscriptions to synchronize.
Syntax
public a_syncpub * upload_defs;
upload_only a_bit_field
Set TRUE to perform upload-only synchronization.
Syntax
public a_bit_field upload_only;
Remarks
Equivalent to the dbmlsync -uo option.
usage_rtn USAGE_CALLBACK
Reserved; use NULL.
Syntax
public USAGE_CALLBACK usage_rtn;
use_fixed_cache a_bit_field
Reserved; use 0.
Syntax
public a_bit_field use_fixed_cache;
use_hex_offsets a_bit_field
Reserved; use 0.
Syntax
public a_bit_field use_hex_offsets;
use_relative_offsets a_bit_field
Reserved; use 0.
Syntax
public a_bit_field use_relative_offsets;
used_dialog_allocation a_bit_field
Reserved; use 0.
Syntax
public a_bit_field used_dialog_allocation;
Programming 805
Database Tools Interface (DBTools)
user_name char *
The MobiLink user to synchronize (deprecated).
Syntax
public char * user_name;
Remarks
Equivalent to the dbmlsync -u option.
verbose a_bit_field
Reserved; use 0.
Syntax
public a_bit_field verbose;
verbose_download a_bit_field
Reserved; use 0.
Syntax
public a_bit_field verbose_download;
verbose_download_data a_bit_field
Reserved; use 0.
Syntax
public a_bit_field verbose_download_data;
verbose_hook a_bit_field
Set TRUE to show hook script information.
Syntax
public a_bit_field verbose_hook;
Remarks
Equivalent to the dbmlsync -vs option.
verbose_minimum a_bit_field
Set TRUE to set verbosity at a minimum.
Syntax
public a_bit_field verbose_minimum;
Remarks
Equivalent to the dbmlsync -v option.
verbose_msgid a_bit_field
Set TRUE to show message IDs.
Syntax
public a_bit_field verbose_msgid;
Remarks
Equivalent to the dbmlsync -vi option.
verbose_option_info a_bit_field
Set TRUE to show command line and extended options.
Syntax
public a_bit_field verbose_option_info;
Remarks
Equivalent to the dbmlsync -vo option.
verbose_protocol a_bit_field
Reserved; use 0.
Syntax
public a_bit_field verbose_protocol;
verbose_row_cnts a_bit_field
Set TRUE to show upload/download row counts.
Syntax
public a_bit_field verbose_row_cnts;
Remarks
Equivalent to the dbmlsync -vn option.
verbose_row_data a_bit_field
Set TRUE to show upload/download row values.
Syntax
public a_bit_field verbose_row_data;
Programming 807
Database Tools Interface (DBTools)
Remarks
Equivalent to the dbmlsync -vr option.
verbose_server a_bit_field
Reserved; use 0.
Syntax
public a_bit_field verbose_server;
verbose_upload a_bit_field
Set TRUE to show upload stream information.
Syntax
public a_bit_field verbose_upload;
Remarks
Equivalent to the dbmlsync -vu option.
verbose_upload_data a_bit_field
Reserved; use 0.
Syntax
public a_bit_field verbose_upload_data;
Syntax
public unsigned short version;
warningrtn MSG_CALLBACK
Function called to display warning messages.
Syntax
public MSG_CALLBACK warningrtn;
a_syncpub structure
Holds information needed for the dbmlsync utility.
Syntax
typedef struct a_syncpub
ext_opt char *
Extended options in the form "keyword=value;...".
Syntax
public char * ext_opt;
Remarks
These are the same options the would follow the dbmlsync -eu option.
Syntax
public struct a_syncpub * next;
pub_name char *
Publication name(s) separated by commas (deprecated).
Syntax
public char * pub_name;
Remarks
This is the same string that would follow the dbmlsync -n option. Only 1 of pub_name and
subscription may be non-NULL.
subscription char *
Subscription name(s) separated by commas.
Syntax
public char * subscription;
Remarks
This is the same string the would follow the dbmlsync -s option. Only 1 of pub_name and
subscription may be non-NULL.
a_sysinfo structure
Holds information needed for dbinfo and dbunload utilities using the DBTools library.
Syntax
typedef struct a_sysinfo
Programming 809
Database Tools Interface (DBTools)
blank_padding a_bit_field
1 if blank padding is used in this database, 0 otherwise.
Syntax
public a_bit_field blank_padding;
case_sensitivity a_bit_field
1 if the database is case sensitive, 0 otherwise.
Syntax
public a_bit_field case_sensitivity;
default_collation char
The collation sequence for the database.
Syntax
public char default_collation;
encryption a_bit_field
1 if the database is encrypted, 0 otherwise.
Syntax
public a_bit_field encryption;
Syntax
public unsigned short page_size;
valid_data a_bit_field
1 to indicate that the other bit fields are valid.
Syntax
public a_bit_field valid_data;
a_table_info structure
Holds information about a table needed as part of the a_db_info structure.
Syntax
typedef struct a_table_info
index_pages a_sql_uint32
Number of index pages.
Syntax
public a_sql_uint32 index_pages;
index_used a_sql_uint32
Number of bytes used in index pages.
Syntax
public a_sql_uint32 index_used;
index_used_pct a_sql_uint32
Index space utilization as a percentage.
Syntax
public a_sql_uint32 index_used_pct;
Syntax
public struct a_table_info * next;
table_id a_sql_uint32
ID number for this table.
Syntax
public a_sql_uint32 table_id;
table_name char *
Name of the table.
Syntax
public char * table_name;
table_pages a_sql_uint32
Number of table pages.
Syntax
public a_sql_uint32 table_pages;
Programming 811
Database Tools Interface (DBTools)
table_used a_sql_uint32
Number of bytes used in table pages.
Syntax
public a_sql_uint32 table_used;
table_used_pct a_sql_uint32
Table space utilization as a percentage.
Syntax
public a_sql_uint32 table_used_pct;
a_translate_log structure
Holds information needed for transaction log translation using the DBTools library.
Syntax
typedef struct a_translate_log
ansi_sql a_bit_field
Set TRUE to produce ANSI standard SQL transactions.
Syntax
public a_bit_field ansi_sql;
Remarks
Set TRUE by dbtran -s option.
chronological_order a_bit_field
Reserved; set to FALSE.
Syntax
public a_bit_field chronological_order;
comment_trigger_trans a_bit_field
Set TRUE to include trigger-generated transactions as comments.
Syntax
public a_bit_field comment_trigger_trans;
Remarks
Set TRUE by dbtran -z option.
confirmrtn MSG_CALLBACK
Address of a confirmation request callback routine or NULL.
Syntax
public MSG_CALLBACK confirmrtn;
Syntax
public const char * connectparms;
Remarks
They take the form of connection strings, such as the following:
"UID=DBA;PWD=sql;DBF=demo.db".
The database server would be started by the connection string START parameter. For
example: "START=c:\SQLAny16\bin32\dbsrv16.exe".
A full example connection string including the START parameter:
"UID=DBA;PWD=sql;DBF=demo.db;START=c:\SQLAny16\bin32\dbsrv16.exe".
debug a_bit_field
Reserved; set to FALSE.
Syntax
public a_bit_field debug;
debug_dump_char a_bit_field
Reserved; set to FALSE.
Syntax
public a_bit_field debug_dump_char;
debug_dump_hex a_bit_field
Reserved; set to FALSE.
Syntax
public a_bit_field debug_dump_hex;
Programming 813
Database Tools Interface (DBTools)
debug_dump_size a_sql_uint32
Reserved, use 0.
Syntax
public a_sql_uint32 debug_dump_size;
debug_page_offsets a_bit_field
Reserved; set to FALSE.
Syntax
public a_bit_field debug_page_offsets;
debug_sql_remote a_bit_field
Reserved; set to FALSE.
Syntax
public a_bit_field debug_sql_remote;
Syntax
public const char * encryption_key;
errorrtn MSG_CALLBACK
Address of an error message callback routine or NULL.
Syntax
public MSG_CALLBACK errorrtn;
extra_audit a_bit_field
Reserved; set to FALSE.
Syntax
public a_bit_field extra_audit;
force_chaining a_bit_field
Reserved; set to FALSE.
Syntax
public a_bit_field force_chaining;
force_recovery a_bit_field
Reserved; set to FALSE.
Syntax
public a_bit_field force_recovery;
generate_reciprocals a_bit_field
Reserved; set to FALSE.
Syntax
public a_bit_field generate_reciprocals;
include_audit a_bit_field
Reserved; set to FALSE.
Syntax
public a_bit_field include_audit;
Syntax
public const char * include_destination_sets;
Syntax
public const char * include_publications;
Syntax
public const char * include_scan_range;
Syntax
public const char * include_source_sets;
Programming 815
Database Tools Interface (DBTools)
include_subsets a_bit_field
Reserved; set to FALSE.
Syntax
public a_bit_field include_subsets;
Syntax
public const char * include_tables;
include_trigger_trans a_bit_field
Set TRUE to include trigger-generated transactions.
Syntax
public a_bit_field include_trigger_trans;
Remarks
Set TRUE by dbtran -t, -g and -sr options.
leave_output_on_error a_bit_field
Set TRUE to leave the generated SQL file if log error detected.
Syntax
public a_bit_field leave_output_on_error;
Remarks
Set TRUE by dbtran -k option.
Syntax
public const char * logname;
logrtn MSG_CALLBACK
Address of a logging callback routine to write messages only to a log file or NULL.
Syntax
public MSG_CALLBACK logrtn;
Syntax
public const char * logs_dir;
Remarks
Equivalent to dbtran -m option. The sqlname pointer must be set and connectparms must be
NULL.
match_mode a_bit_field
Reserved; set to FALSE.
Syntax
public a_bit_field match_mode;
Syntax
public const char * match_pos;
msgrtn MSG_CALLBACK
Address of an information message callback routine or NULL.
Syntax
public MSG_CALLBACK msgrtn;
omit_comments a_bit_field
Reserved; set to FALSE.
Syntax
public a_bit_field omit_comments;
Syntax
public const char * queueparms;
Programming 817
Database Tools Interface (DBTools)
quiet a_bit_field
Set to TRUE to operate without printing messages.
Syntax
public a_bit_field quiet;
Remarks
Set TRUE by dbtran -q option.
recovery_bytes a_sql_uint32
Reserved, use 0.
Syntax
public a_sql_uint32 recovery_bytes;
recovery_ops a_sql_uint32
Reserved, use 0.
Syntax
public a_sql_uint32 recovery_ops;
remove_rollback a_bit_field
Set to FALSE if you want to include rollback transactions in output.
Syntax
public a_bit_field remove_rollback;
Remarks
Set FALSE by dbtran -a option.
replace a_bit_field
Set TRUE to replace the SQL file without a confirmation.
Syntax
public a_bit_field replace;
Remarks
Set TRUE by dbtran -y option.
Syntax
public const char * repserver_users;
show_undo a_bit_field
Reserved; set to FALSE.
Syntax
public a_bit_field show_undo;
since_checkpoint a_bit_field
Set TRUE for output from most recent checkpoint.
Syntax
public a_bit_field since_checkpoint;
Remarks
Set TRUE by dbtran -f option.
since_time a_sql_uint32
Output from most recent checkpoint before time.
Syntax
public a_sql_uint32 since_time;
Remarks
The number of minutes since January 1, 0001. Equivalent to dbtran -j option.
Syntax
public const char * sqlname;
Remarks
If NULL, then the name is based on the transaction log file name. Equivalent to dbtran -n
option.
Programming 819
Database Tools Interface (DBTools)
statusrtn MSG_CALLBACK
Address of a status message callback routine or NULL.
Syntax
public MSG_CALLBACK statusrtn;
use_hex_offsets a_bit_field
Reserved; set to FALSE.
Syntax
public a_bit_field use_hex_offsets;
use_relative_offsets a_bit_field
Reserved; set to FALSE.
Syntax
public a_bit_field use_relative_offsets;
userlist p_name
A linked list of user names.
Syntax
public p_name userlist;
Remarks
Equivalent to dbtran -u user1,... or -x user1,... Select or omit transactions for listed users.
userlisttype char
Set to DBTRAN_INCLUDE_ALL unless you want to include or exclude a list of users.
Syntax
public char userlisttype;
Remarks
DBTRAN_INCLUDE_SOME for -u, or DBTRAN_EXCLUDE_SOME for -x.
Syntax
public unsigned short version;
a_truncate_log structure
Holds information needed for transaction log truncation using the DBTools library.
Syntax
typedef struct a_truncate_log
Syntax
public const char * connectparms;
Remarks
They take the form of connection strings, such as the following:
"UID=DBA;PWD=sql;DBF=demo.db".
The database server would be started by the connection string START parameter. For
example: "START=c:\SQLAny16\bin32\dbsrv16.exe".
A full example connection string including the START parameter:
"UID=DBA;PWD=sql;DBF=demo.db;START=c:\SQLAny16\bin32\dbsrv16.exe".
errorrtn MSG_CALLBACK
Address of an error message callback routine or NULL.
Syntax
public MSG_CALLBACK errorrtn;
msgrtn MSG_CALLBACK
Address of an information message callback routine or NULL.
Syntax
public MSG_CALLBACK msgrtn;
quiet a_bit_field
Set TRUE to operate without printing messages.
Syntax
public a_bit_field quiet;
Remarks
Set TRUE by dbbackup -q option.
Programming 821
Database Tools Interface (DBTools)
server_backup a_bit_field
Set TRUE to indicate backup on server using BACKUP DATABASE.
Syntax
public a_bit_field server_backup;
Remarks
Set TRUE by dbbackup -s option when dbbackup -x option is specified.
truncate_interrupted char
Truncate was interrupted if non-zero.
Syntax
public char truncate_interrupted;
Syntax
public unsigned short version;
a_validate_db structure
Holds information needed for database validation using the DBTools library.
Syntax
typedef struct a_validate_db
Syntax
public const char * connectparms;
Remarks
They take the form of connection strings, such as the following:
"UID=DBA;PWD=sql;DBF=demo.db".
The database server would be started by the connection string START parameter. For
example: "START=c:\SQLAny16\bin32\dbsrv16.exe".
A full example connection string including the START parameter:
"UID=DBA;PWD=sql;DBF=demo.db;START=c:\SQLAny16\bin32\dbsrv16.exe".
errorrtn MSG_CALLBACK
Address of an error message callback routine or NULL.
Syntax
public MSG_CALLBACK errorrtn;
index a_bit_field
Set TRUE to validate indexes.
Syntax
public a_bit_field index;
Remarks
The tables field points to a list of indexes. Set TRUE by dbvalid -i option. Set FALSE by
dbvalid -t option.
msgrtn MSG_CALLBACK
Address of an information message callback routine or NULL.
Syntax
public MSG_CALLBACK msgrtn;
quiet a_bit_field
Set TRUE to operate without printing messages.
Syntax
public a_bit_field quiet;
Remarks
Set TRUE by dbvalid -q option.
statusrtn MSG_CALLBACK
Address of a status message callback routine or NULL.
Syntax
public MSG_CALLBACK statusrtn;
tables p_name
Pointer to a linked list of table names or index names (when the index field is set TRUE).
Syntax
public p_name tables;
Programming 823
Database Tools Interface (DBTools)
Remarks
This is set by the dbvalid object-name-list argument.
type char
The type of validation to perform.
Syntax
public char type;
Remarks
One of VALIDATE_NORMAL, VALIDATE_EXPRESS, VALIDATE_CHECKSUM, etc.
See Validation enumeration.
Syntax
public unsigned short version;
an_erase_db structure
Holds information needed to erase a database using the DBTools library.
Syntax
typedef struct an_erase_db
confirmrtn MSG_CALLBACK
Address of a confirmation request callback routine or NULL.
Syntax
public MSG_CALLBACK confirmrtn;
Syntax
public const char * dbname;
Syntax
public const char * encryption_key;
Remarks
Equivalent to dberase -ek or -ep options.
erase a_bit_field
Erase without confirmation (1) or with confirmation (0).
Syntax
public a_bit_field erase;
Remarks
Set TRUE by dberase -y option.
errorrtn MSG_CALLBACK
Address of an error message callback routine or NULL.
Syntax
public MSG_CALLBACK errorrtn;
msgrtn MSG_CALLBACK
Address of an information message callback routine or NULL.
Syntax
public MSG_CALLBACK msgrtn;
quiet a_bit_field
Operate without printing messages (1), or print messages (0).
Syntax
public a_bit_field quiet;
Remarks
Set TRUE by dberase -q option.
Syntax
public unsigned short version;
Programming 825
Database Tools Interface (DBTools)
an_unload_db structure
Holds information needed to unload a database using the DBTools library or extract a remote
database for SQL Remote.
Syntax
typedef struct an_unload_db
Remarks
Those fields used by the dbxtract SQL Remote Extraction utility are indicated.
compress_output a_bit_field
Set TRUE to compress table data files.
Syntax
public a_bit_field compress_output;
Remarks
Set TRUE by dbunload -cp option.
confirmrtn MSG_CALLBACK
Address of a confirmation request callback routine or NULL.
Syntax
public MSG_CALLBACK confirmrtn;
Syntax
public const char * connectparms;
Remarks
They take the form of connection strings, such as the following:
"UID=DBA;PWD=sql;DBF=demo.db".
The database server would be started by the connection string START parameter. For
example: "START=c:\SQLAny16\bin32\dbsrv16.exe".
A full example connection string including the START parameter:
"UID=DBA;PWD=sql;DBF=demo.db;START=c:\SQLAny16\bin32\dbsrv16.exe".
debug a_bit_field
Reserved; set FALSE.
Syntax
public a_bit_field debug;
display_create a_bit_field
Set TRUE to display database creation command (sql or dbinit).
Syntax
public a_bit_field display_create;
Remarks
Set TRUE by dbunload -cm sql or -cm dbinit option.
display_create_dbinit a_bit_field
Set TRUE to display dbinit database creation command.
Syntax
public a_bit_field display_create_dbinit;
Remarks
Set TRUE by dbunload -cm dbinit option.
encrypted_tables a_bit_field
Set TRUE to enable encrypted tables in new database (with -an or -ar).
Syntax
public a_bit_field encrypted_tables;
Remarks
Set TRUE by dbunload/dbxtract -et option.
Syntax
public const char * encryption_algorithm;
Remarks
Set by dbunload/dbxtract -ea option.
Programming 827
Database Tools Interface (DBTools)
Syntax
public const char * encryption_key;
Remarks
Set by dbunload/dbxtract -ek or -ep option.
errorrtn MSG_CALLBACK
Address of an error message callback routine or NULL.
Syntax
public MSG_CALLBACK errorrtn;
escape_char char
The escape character (normally, "\").
Syntax
public char escape_char;
Remarks
Used when escape_char_present is TRUE. Set TRUE by dbunload/dbxtract -p option.
escape_char_present a_bit_field
Set TRUE to indicate that the escape character in escape_char is defined.
Syntax
public a_bit_field escape_char_present;
Remarks
Set TRUE by dbunload/dbxtract -p option.
exclude_foreign_keys a_bit_field
Set TRUE to exclude foreign keys.
Syntax
public a_bit_field exclude_foreign_keys;
Remarks
Set TRUE by dbxtract -xf option.
exclude_hooks a_bit_field
Set TRUE to exclude procedure hooks.
Syntax
public a_bit_field exclude_hooks;
Remarks
Set TRUE by dbxtract -xh option.
exclude_procedures a_bit_field
Set TRUE to exclude stored procedures.
Syntax
public a_bit_field exclude_procedures;
Remarks
Set TRUE by dbxtract -xp option.
exclude_tables a_bit_field
Set FALSE to indicate that the list contains tables to be included.
Syntax
public a_bit_field exclude_tables;
Remarks
Set TRUE to indicate that the list contains tables to be excluded. Set TRUE by dbunload -e
option.
exclude_triggers a_bit_field
Set TRUE to exclude triggers.
Syntax
public a_bit_field exclude_triggers;
Remarks
Set TRUE by dbxtract -xt option.
exclude_views a_bit_field
Set TRUE to exclude views.
Syntax
public a_bit_field exclude_views;
Programming 829
Database Tools Interface (DBTools)
Remarks
Set TRUE by dbxtract -xv option.
extract a_bit_field
Set TRUE if performing a remote database extraction.
Syntax
public a_bit_field extract;
Remarks
Set FALSE by dbunload. Set TRUE by dbxtract.
genscript a_bit_field
Reserved; set FALSE.
Syntax
public a_bit_field genscript;
include_where_subscribe a_bit_field
Set TRUE to extract fully qualified publications.
Syntax
public a_bit_field include_where_subscribe;
Remarks
Set TRUE by dbxtract -f option.
Syntax
public unsigned short isolation_level;
Remarks
Set by dbxtract -l option.
isolation_set a_bit_field
Set TRUE to indicate that isolation_level has been set for all extraction operations.
Syntax
public a_bit_field isolation_set;
Remarks
Set TRUE by dbxtract -l option.
Syntax
public const char * locale;
make_auxiliary a_bit_field
Set TRUE to make auxiliary catalog (for use with diagnostic tracing).
Syntax
public a_bit_field make_auxiliary;
Remarks
Set TRUE by dbunload -k option.
Syntax
public const char * ms_filename;
ms_reserve int
Reserved; use 0.
Syntax
public int ms_reserve;
ms_size int
Reserved; use 0.
Syntax
public int ms_size;
msgrtn MSG_CALLBACK
Address of an information message callback routine or NULL.
Syntax
public MSG_CALLBACK msgrtn;
Programming 831
Database Tools Interface (DBTools)
no_confirm a_bit_field
Set TRUE to replace an existing SQL script file without confirmation.
Syntax
public a_bit_field no_confirm;
Remarks
Set by dbunload/dbxtract -y option.
no_reload_status a_bit_field
Set TRUE to suppress reload status messages for tables and indexes.
Syntax
public a_bit_field no_reload_status;
Remarks
Set TRUE by dbunload -qr option.
notemp_size long
Reserved; use 0.
Syntax
public long notemp_size;
preserve_identity_values a_bit_field
Set TRUE to preserve identity values for AUTOINCREMENT columns.
Syntax
public a_bit_field preserve_identity_values;
Remarks
Set TRUE by dbunload -l option.
preserve_ids a_bit_field
Set TRUE to preserve user IDs.
Syntax
public a_bit_field preserve_ids;
Remarks
This is the normal setting. Set FALSE by dbunload -e option.
profiling_uses_single_dbspace a_bit_field
Set TRUE to collapse to a single dbspace file (for use with diagnostic tracing).
Syntax
public a_bit_field profiling_uses_single_dbspace;
Remarks
Set TRUE by dbunload -kd option.
recompute a_bit_field
Set TRUE to redo computed columns.
Syntax
public a_bit_field recompute;
Remarks
Set TRUE by dbunload -dc option.
refresh_mat_view a_bit_field
Set TRUE to generate statements to refresh text indexes and valid materialized views.
Syntax
public a_bit_field refresh_mat_view;
Remarks
Set TRUE by dbunload/dbxtract -g option.
reload_connectparms char *
Connection parameters such as user ID, password, and database for the reload database.
Syntax
public char * reload_connectparms;
Remarks
Set by dbunload/dbxtract -ac option.
reload_db_filename char *
Name of the new database file to create and reload.
Syntax
public char * reload_db_filename;
Programming 833
Database Tools Interface (DBTools)
Remarks
Set by dbunload/dbxtract -an option.
reload_db_logname char *
Filename of the new database transaction log or NULL.
Syntax
public char * reload_db_logname;
Remarks
Set by dbxtract -al option.
Syntax
public const char * reload_filename;
Remarks
Set by dbunload -r option.
Syntax
public unsigned short reload_page_size;
Remarks
Set by dbunload -ap option.
Syntax
public const char * remote_dir;
remove_encrypted_tables a_bit_field
Set TRUE to remove encryption from encrypted tables.
Syntax
public a_bit_field remove_encrypted_tables;
Remarks
Set TRUE by dbunload/dbxtract -er option.
replace_db a_bit_field
Set TRUE to replace the database.
Syntax
public a_bit_field replace_db;
Remarks
Set TRUE by dbunload -ar option.
runscript a_bit_field
Reserved; set FALSE.
Syntax
public a_bit_field runscript;
schema_reload a_bit_field
Reserved; set FALSE.
Syntax
public a_bit_field schema_reload;
Syntax
public const char * site_name;
start_subscriptions a_bit_field
Set TRUE to start subscriptions.
Syntax
public a_bit_field start_subscriptions;
Remarks
This is the default for dbxtract. Set FALSE by dbxtract -b option.
Programming 835
Database Tools Interface (DBTools)
Syntax
public const char * startline;
startline_name a_bit_field
Reserved; set FALSE.
Syntax
public a_bit_field startline_name;
Syntax
public const char * startline_old;
statusrtn MSG_CALLBACK
Address of a status message callback routine or NULL.
Syntax
public MSG_CALLBACK statusrtn;
Syntax
public const char * subscriber_username;
suppress_statistics a_bit_field
Set TRUE to suppress inclusion of column statistics.
Syntax
public a_bit_field suppress_statistics;
Remarks
Set TRUE by dbunload -ss option.
sysinfo a_sysinfo
Reserved; use NULL.
Syntax
public a_sysinfo sysinfo;
table_list p_name
Selective table list.
Syntax
public p_name table_list;
Remarks
Set by dbunload -e and -t options.
table_list_provided a_bit_field
Set TRUE to indicate that a list of tables has been provided.
Syntax
public a_bit_field table_list_provided;
Remarks
See table_list field. Set TRUE by dbunload -e or -t options.
Syntax
public const char * temp_dir;
Syntax
public const char * template_name;
unload_interrupted char
Reserved; set to 0.
Syntax
public char unload_interrupted;
Programming 837
Database Tools Interface (DBTools)
unload_type char
Set Unload enumeration (UNLOAD_ALL and so on).
Syntax
public char unload_type;
Remarks
Set by dbunload/dbxtract -d, -k, -n options.
unordered a_bit_field
Set TRUE for unordered data.
Syntax
public a_bit_field unordered;
Remarks
Indexes will not be used to unload data. Set by dbunload/dbxtract -u option.
use_internal_reload a_bit_field
Set TRUE to perform an internal reload.
Syntax
public a_bit_field use_internal_reload;
Remarks
This is the normal setting. Set TRUE by dbunload/dbxtract -ii and -xi option. Set FALSE by
dbunload/dbxtract -ix and -xx option.
use_internal_unload a_bit_field
Set TRUE to Perform an internal unload.
Syntax
public a_bit_field use_internal_unload;
Remarks
Set TRUE by dbunload/dbxtract -i? option. Set FALSE by dbunload/dbxtract -x? option.
verbose char
See Verbosity enumeration (VB_QUIET, VB_NORMAL, VB_VERBOSE).
Syntax
public char verbose;
Syntax
public unsigned short version;
an_upgrade_db structure
Holds information needed to upgrade a database using the DBTools library.
Syntax
typedef struct an_upgrade_db
Syntax
public const char * connectparms;
Remarks
They take the form of connection strings, such as the following:
"UID=DBA;PWD=sql;DBF=demo.db".
The database server would be started by the connection string START parameter. For
example: "START=c:\SQLAny16\bin32\dbsrv16.exe".
A full example connection string including the START parameter:
"UID=DBA;PWD=sql;DBF=demo.db;START=c:\SQLAny16\bin32\dbsrv16.exe".
errorrtn MSG_CALLBACK
Address of an error message callback routine or NULL.
Syntax
public MSG_CALLBACK errorrtn;
jconnect a_bit_field
Set TRUE to upgrade the database to include jConnect procedures.
Syntax
public a_bit_field jconnect;
Remarks
Set FALSE by dbupgrad -i option.
Programming 839
Database Tools Interface (DBTools)
msgrtn MSG_CALLBACK
Address of an information message callback routine or NULL.
Syntax
public MSG_CALLBACK msgrtn;
quiet a_bit_field
Set TRUE to operate without printing messages.
Syntax
public a_bit_field quiet;
Remarks
Set TRUE by dbupgrad -q option.
restart a_bit_field
Set TRUE to restart the database after the upgrade.
Syntax
public a_bit_field restart;
Remarks
Set FALSE by the dbupgrad -nrs option.
statusrtn MSG_CALLBACK
Address of a status message callback routine or NULL.
Syntax
public MSG_CALLBACK statusrtn;
Syntax
public unsigned short sys_proc_definer;
Remarks
When upgrading from a version 16.0 or later database retain the current SQL SECURITY
model (same as not specifying -pd).
Assign 1 to upgrade the database to have the pre-16.0 SQL SECURITY model for legacy
system stored procedures (same as -pd y)
Assign 2 to upgrade the database to have the pre-16.0 SQL SECURITY model for legacy
system stored procedures (same as -pd n).
Syntax
public unsigned short version;
Programming 841
Database Tools Interface (DBTools)
About OLAP
The analytic functions, which offer the ability to perform complex data analysis within a
single SQL statement, are facilitated by a category of software technology named online
analytical processing (OLAP). Its functions are shown in the following list:
• GROUP BY clause extensions – CUBE and ROLLUP
• Analytical functions:
• Simple aggregates – AVG, COUNT, MAX, MIN, and SUM, STDDEV and VARIANCE
Note: You can use simple aggregate functions, except Grouping(), with an OLAP
windowed function.
• Window functions:
• Windowing aggregates – AVG, COUNT, MAX, MIN, and SUM
• Ranking functions – RANK, DENSE_RANK, PERCENT_RANK, and NTILE
• Statistical functions – STDDEV, STDDEV_SAMP, STDDEV_POP, VARIANCE,
VAR_POP, VAR_SAMP, REGR_AVGX, REGR_AVGY, REGR_COUNT,
REGR_INTERCEPT, REGR_R2, REGR_SLOPE, REGR_SXX, REGR_SXY,
REGR_SYY, CORR, COVAR_POP, COVAR_SAMP, CUME_DIST,
EXP_WEIGHTED_AVG, and WEIGHTED_AVG.
• Distribution functions – PERCENTILE_CONT and PERCENTILE_DISC
• Numeric functions – WIDTH_BUCKET, CEIL, and LN, EXP, POWER, SQRT, and
FLOOR
Extensions to the ANSI SQL standard to include complex data analysis were introduced as an
amendment to the 1999 SQL standard. SAP Sybase IQ SQL enhancements support these
extensions.
Some database products provide a separate OLAP module that requires you to move data from
the database into the OLAP module before analyzing it. By contrast, SAP Sybase IQ builds
Programming 843
Appendix: Using OLAP
OLAP features into the database itself, making deployment and integration with other
database features, such as stored procedures, easy and seamless.
OLAP Benefits
OLAP functions, when combined with the GROUPING, CUBE, and ROLLUP extensions,
provide two primary benefits.
First, they let you perform multidimensional data analysis, data mining, time series analyses,
trend analysis, cost allocations, goal seeking, ad hoc multidimensional structural changes,
nonprocedural modeling, and exception alerting, often with a single SQL statement. Second,
the window and reporting aggregate functions use a relational operator, called a window that
can be executed more efficiently than semantically equivalent queries that use self-joins or
correlated subqueries. The result sets you obtain using OLAP can have subtotal rows and can
be organized into multidimensional cubes.
Moving averages and moving sums can be calculated over various intervals; aggregations and
ranks can be reset as selected column values change; and complex ratios can be expressed in
simple terms. Within the scope of a single query expression, you can define several different
OLAP functions, each with its own partitioning rules.
OLAP Evaluation
OLAP evaluation can be conceptualized as several phases of query execution that contribute
to the final result.
You can identify OLAP phases of execution by the relevant clause in the query. For example, if
a SQL query specification contains window functions, the WHERE, JOIN, GROUP BY, and
HAVING clauses are processed first. Partitions are created after the groups defined in the
GROUP BY clause and before the evaluation of the final SELECT list in the query’s ORDER BY
clause.
For the purpose of grouping, all NULL values are considered to be in the same group, even
though NULL values are not equal to one another.
The HAVING clause acts as a filter, much like the WHERE clause, on the results of the GROUP
BY clause.
Consider the semantics of a simple query specification involving the SQL statements and
clauses, SELECT, FROM, WHERE, GROUP BY, and HAVING from the ANSI SQL standard:
1. The query produces a set of rows that satisfy the table expressions present in the FROM
clause.
2. Predicates from the WHERE clause are applied to rows from the table. Rows that fail to
satisfy the WHERE clause conditions (do not equal true) are rejected.
3. Except for aggregate functions, expressions from the SELECT list and in the list and
GROUP BY clause are evaluated for every remaining row.
4. The resulting rows are grouped together based on distinct values of the expressions in the
GROUP BY clause, treating NULL as a special value in each domain. The expressions in
the GROUP BY clause serve as partition keys if a PARTITION BY clause is present.
5. For each partition, the aggregate functions present in the SELECT list or HAVING clause
are evaluated. Once aggregated, individual table rows are no longer present in the
intermediate result set. The new result set consists of the GROUP BY expressions and the
values of the aggregate functions computed for each partition.
6. Conditions from the HAVING clause are applied to result groups. Groups are eliminated
that do not satisfy the HAVING clause.
7. Results are partitioned on boundaries defined in the PARTITION BY clause. OLAP
windows functions (rank and aggregates) are computed for result windows.
Prefixes
A list of prefixes is constructed for any query that contains a GROUP BY clause. A prefix is a
subset of the items in the GROUP BY clause and is constructed by excluding one or more of the
rightmost items from those in the query’s GROUP BY clause. The remaining columns are
called the prefix columns.
ROLLUP example 1—In the following ROLLUP example query, the GROUP BY list includes
two variables, Year and Quarter:
SELECT year (OrderDate) AS Year, quarter(OrderDate)
AS Quarter, COUNT(*) Orders
FROM SalesOrders
Programming 845
Appendix: Using OLAP
Note: The GROUP BY list contains the same number of prefixes as items.
Group by ROLLUP
The ROLLUP operator requires an ordered list of grouping expressions to be supplied as
arguments.
ROLLUP syntax.
SELECT … [ GROUPING (column-name) … ] …
GROUP BY [ expression [, …]
| ROLLUP ( expression [, …] ) ]
GROUPING takes a column name as a parameter and returns a Boolean value as listed in the
following table:
ROLLUP first calculates the standard aggregate values specified in the GROUP BY clause.
Then ROLLUP moves from right to left through the list of grouping columns and creates
progressively higher-level subtotals. A grand total is created at the end. If n is the number of
grouping columns, then ROLLUP creates n+1 levels of subtotals.
This SQL Syntax... Defines the Following Sets...
GROUP BY ROLLUP (A, B, C); (A, B, C)
(A, B)
(A)
()
Subtotal rows can help you analyze data, especially if there are large amounts of data, different
dimensions to the data, data contained in different tables, or even different databases
altogether. For example, a sales manager might find reports on sales figures broken down by
sales representative, region, and quarter to be useful in understanding patterns in sales.
Subtotals for the data give the sales manager a picture of overall sales from different
perspectives. Analyzing this data is easier when summary information is provided based on
the criteria that the sales manager wants to compare.
With OLAP, the procedure for analyzing and computing row and column subtotals is invisible
to users.
Programming 847
Appendix: Using OLAP
Figure 2: Subtotals
1. This step yields an intermediate result set that has not yet considered the ROLLUP.
2. Subtotals are evaluated and attached to the result set.
3. The rows are arranged according to the ORDER BY clause in the query.
667 2000 34 0 0
949 2000 31 0 0
1142 2000 33 0 0
NULL 2001 66 1 0
667 2001 20 0 0
949 2001 22 0 0
1142 2001 24 0 0
For each prefix, a subtotal row is constructed that corresponds to all rows in which the prefix
columns have the same value.
To demonstrate ROLLUP results, examine the example query again:
SELECT year (OrderDate) AS Year, quarter
(OrderDate) AS Quarter, COUNT (*) Orders
FROM SalesOrders
GROUP BY ROLLUP (Year, Quarter)
ORDER BY Year, Quarter
In this query, the prefix containing the Year column leads to a summary row for Year=2000
and a summary row for Year=2001. A single summary row for the prefix has no columns,
which is a subtotal over all rows in the intermediate result set.
The value of each column in a subtotal row is as follows:
• Column included in the prefix – the value of the column. For example, in the preceding
query, the value of the Year column for the subtotal over rows with Year=2000 is 2000.
• Column excluded from the prefix – NULL. For example, the Quarter column has a
value of NULL for the subtotal rows generated by the prefix consisting of the Year column.
• Aggregate function – an aggregate over the values of the excluded columns.
Subtotal values are computed over the rows in the underlying data, not over the aggregated
rows. In many cases, such as SUM or COUNT, the result is the same, but the distinction is
important in the case of statistical functions such as AVG, STDDEV, and VARIANCE, for
which the result differs.
Restrictions on the ROLLUP operator are:
• The ROLLUP operator supports all of the aggregate functions available to the GROUP BY
clause except COUNT DISTINCT and SUM DISTINCT.
• ROLLUP can only be used in the SELECT statement; you cannot use ROLLUP in a
subquery.
• A grouping specification that combines multiple ROLLUP, CUBE, and GROUP BY
columns in the same GROUP BY clause is not currently supported.
• Constant expressions as GROUP BY keys are not supported.
ROLLUP example 2—The following example illustrates the use of ROLLUP and GROUPING
and displays a set of mask columns created by GROUPING. The digits 0 and 1 displayed in
columns S, N, and C are the values returned by GROUPING to represent the value of the
ROLLUP result. A program can analyze the results of this query by using a mask of “011” to
identify subtotal rows and “111” to identify the row of overall totals.
Programming 849
Appendix: Using OLAP
ROLLUP example 4—The next example query returns data that summarizes the number of
sales orders by year and quarter.
SELECT year (OrderDate) AS Year,
quarter(OrderDate) AS Quarter, COUNT (*) Orders
FROM SalesOrders
GROUP BY ROLLUP (Year, Quarter)
ORDER BY Year, Quarter
The following figure illustrates the query results with subtotal rows highlighted in the result
set. Each subtotal row contains a NULL value in the column or columns over which the
subtotal is computed.
Programming 851
Appendix: Using OLAP
Row [1] represents the total number of orders across both years (2000, 2001) and all quarters.
This row contains NULL in both the Year and Quarter columns and is the row where all
columns were excluded from the prefix.
Note: Every ROLLUP operation returns a result set with one row where NULL appears in each
column except for the aggregate column. This row represents the summary of each column to
the aggregate function. For example, if SUM were the aggregate function in question, this row
would represent the grand total of all values.
Row [2] represent the total number of orders in the years 2000 and 2001, respectively. Both
rows contain NULL in the Quarter column because the values in that column are rolled up
to give a subtotal for Year. The number of rows like this in your result set depends on the
number of variables that appear in your ROLLUP query.
The remaining rows marked [3] provide summary information by giving the total number of
orders for each quarter in both years.
ROLLUP example 5—This example of the ROLLUP operation returns a slightly more
complicated result set, which summarizes the number of sales orders by year, quarter, and
region. In this example, only the first and second quarters and two selected regions (Canada
and the Eastern region) are examined.
SELECT year(OrderDate) AS Year, quarter(OrderDate)AS Quarter,
region, COUNT(*) AS Orders
FROM SalesOrders WHERE region IN ('Canada','Eastern') AND quarter IN
(1, 2)
GROUP BY ROLLUP (Year, Quarter, Region)ORDER BY Year, Quarter, Region
The following figure illustrates the result set from the above query. Each subtotal row contains
a NULL in the column or columns over which the subtotal is computed.
Row [1] is an aggregate over all rows and contains NULL in the Year, Quarter, and
Region columns. The value in the Orders column of this row represents the total number of
orders in Canada and the Eastern region in quarters 1 and 2 in the years 2000 and 2001.
The rows marked [2] represent the total number of sales orders in each year (2000) and (2001)
in quarters 1 and 2 in Canada and the Eastern region. The values of these rows [2] are equal to
the grand total represented in row [1].
The rows marked [3] provide data about the total number of orders for the given year and
quarter by region.
Programming 853
Appendix: Using OLAP
The rows marked [4] provide data about the total number of orders for each year, each quarter,
and each region in the result set.
Group by CUBE
The CUBE operator in the GROUP BY clause analyzes data by forming the data into groups in
more than one dimension (grouping expression).
CUBE requires an ordered list of dimensions as arguments and enables the SELECT statement
to calculate subtotals for all possible combinations of the group of dimensions that you specify
in the query and generates a result set that shows aggregates for all combinations of values in
selected columns.
CUBE syntax:
SELECT … [ GROUPING (column-name) … ] …
GROUP BY [ expression [,…]
| CUBE ( expression [,…] ) ]
GROUPING takes a column name as a parameter, and returns a Boolean value as listed in the
following table:
CUBE is particularly useful when your dimensions are not a part of the same hierarchy.
Programming 855
Appendix: Using OLAP
• CUBE is currently not supported with the inverse distribution analytical functions,
PERCENTILE_CONT and PERCENTILE_DISC.
• CUBE can only be used in the SELECT statement; you cannot use CUBE in a SELECT
subquery.
• A GROUPING specification that combines ROLLUP, CUBE, and GROUP BY columns in
the same GROUP BY clause is not currently supported.
• Constant expressions as GROUP BY keys are not supported.
Note: CUBE performance diminishes if the size of the cube exceeds the size of the temp
cache.
GROUPING can be used with the CUBE operator to distinguish between stored NULL values
and NULL values in query results created by CUBE.
See the examples in the description of the ROLLUP operator for illustrations of the use of the
GROUPING function to interpret results.
All CUBE operations return result sets with at least one row where NULL appears in each
column except for the aggregate columns. This row represents the summary of each column to
the aggregate function.
CUBE example 1—The following queries use data from a census, including the state
(geographic location), gender, education level, and income of people. The first query contains
a GROUP BY clause that organizes the results of the query into groups of rows, according to
the values of the columns state, gender, and education in the table census and
computes the average income and the total counts of each group. This query uses only the
GROUP BY clause without the CUBE operator to group the rows.
SELECT State, Sex as gender, DepartmentID,
COUNT(*),CAST(ROUND(AVG(Salary),2) AS NUMERIC(18,2))AS AVERAGEFROM
employees WHERE state IN ('MA' , 'CA')GROUP BY State, Sex,
DepartmentIDORDER BY 1,2;
Use the CUBE extension of the GROUP BY clause, if you want to compute the average income
in the entire census of state, gender, and education and compute the average income in all
possible combinations of the columns state, gender, and education, while making
only a single pass through the census data. For example, use the CUBE operator if you want to
compute the average income of all females in all states, or compute the average income of all
people in the census according to their education and geographic location.
When CUBE calculates a group, a NULL value is generated for the columns whose group is
calculated. The GROUPING function must be used to distinguish whether a NULL is a NULL
stored in the database or a NULL resulting from CUBE. The GROUPING function returns 1 if
the designated column has been merged to a higher level group.
CUBE example 2—The following query illustrates the use of the GROUPING function with
GROUP BY CUBE.
SELECT case grouping(State) WHEN 1 THEN 'ALL' ELSE StateEND AS
c_state, case grouping(sex) WHEN 1 THEN 'ALL'ELSE Sex end AS
c_gender, case grouping(DepartmentID)WHEN 1 THEN 'ALL' ELSE
cast(DepartmentID as char(4)) endAS c_dept, COUNT(*),
CAST(ROUND(AVG(salary),2) ASNUMERIC(18,2))AS AVERAGEFROM employees
WHERE state IN ('MA' , 'CA')GROUP BY CUBE(state, sex,
DepartmentID)ORDER BY 1,2,3;
The results of this query are shown below. The NULLs generated by CUBE to indicate a
subtotal row are replaced with ALL in the subtotal rows, as specified in the query.
c_state c_gender c_dept COUNT() AVERAGE
------- -------- ------- ----- --------
ALL ALL 200 3 52200.00
ALL ALL ALL 3 52200.00
ALL F 200 2 58650.00
ALL F ALL 2 58650.00
ALL M 200 1 39300.00
ALL M ALL 1 39300.00
CA ALL 200 3 52200.00
CA ALL ALL 3 52200.00
CA F 200 2 58650.00
CA F ALL 2 58650.00
CA M 200 1 39300.00
CA M ALL 1 39300.00
CUBE example 3—In this example, the query returns a result set that summarizes the total
number of orders and then calculates subtotals for the number of orders by year and quarter.
Note: As the number of variables that you want to compare increases, the cost of computing
the cube increases exponentially.
SELECT year (OrderDate) AS Year, quarter(OrderDate) AS Quarter, COUNT
(*) OrdersFROM SalesOrdersGROUP BY CUBE (Year, Quarter)ORDER BY Year,
Quarter
The figure that follows represents the result set from the query. The subtotal rows are
highlighted in the result set. Each subtotal row has a NULL in the column or columns over
which the subtotal is computed.
Programming 857
Appendix: Using OLAP
The first highlighted row [1] represents the total number of orders across both years and all
quarters. The value in the Orders column is the sum of the values in each of the rows marked
[3]. It is also the sum of the four values in the rows marked [2].
The next set of highlighted rows [2] represents the total number of orders by quarter across
both years. The two rows marked by [3] represent the total number of orders across all quarters
for the years 2000 and 2001, respectively.
Analytical Functions
SAP Sybase IQ offers both simple and windowed aggregation functions that offer the ability to
perform complex data analysis within a single SQL statement.
You can use these functions to compute results for queries such as “What is the quarterly
moving average of the Dow Jones Industrial average,” or “List all employees and their
cumulative salaries for each department.” Moving averages and cumulative sums can be
calculated over various intervals, and aggregations and ranks can be partitioned, so aggregate
calculation is reset when partition values change. Within the scope of a single query
expression, you can define several different OLAP functions, each with its own arbitrary
partitioning rules. Analytical functions can be broken into two categories:
• Simple aggregate functions, such as AVG, COUNT, MAX, MIN, and SUM summarize data
over a group of rows from the database. The groups are formed using the GROUP BY
clause of the SELECT statement.
• Unary statistical aggregate functions that take one argument include STDDEV,
STDDEV_SAMP, STDDEV_POP, VARIANCE, VAR_SAMP, and VAR_POP.
Both the simple and unary categories of aggregates summarize data over a group of rows from
the database and can be used with a window specification to compute a moving window over a
result set as it is processed.
Note: The aggregate functions AVG, SUM, STDDEV, STDDEV_POP, STDDEV_SAMP,
VAR_POP, VAR_SAMP, and VARIANCE do not support binary data types BINARY and
VARBINARY.
Note: With the exception of Grouping() functions, both the simple and unary aggregates can
be used in a windowing function that incorporates a <window clause> in a SQL query
specification (a window) that conceptually creates a moving window over a result set as it is
processed.
Windowing
A major feature of the ANSI SQL extensions for OLAP is a construct called a window. This
windowing extension lets users divide result sets of a query (or a logical partition of a query)
into groups of rows called partitions and determine subsets of rows to aggregate with respect
to the current row.
You can use three classes of window functions with a window: ranking functions, the row
numbering function, and window aggregate functions.
<WINDOWED TABLE FUNCTION TYPE> ::=
<RANK FUNCTION TYPE> <LEFT PAREN> <RIGHT PAREN>
| ROW_NUMBER <LEFT PAREN> <RIGHT PAREN>
| <WINDOW AGGREGATE FUNCTION>
Windowing extensions specify a window function type over a window name or specification
and are applied to partitioned result sets within the scope of a single query expression. A
window partition is a subset of rows returned by a query, as defined by one or more columns in
a special OVER clause:
olap_function() OVER (PARTITION BY col1, col2...)
Windowing operations let you establish information such as the ranking of each row within its
partition, the distribution of values in rows within a partition, and similar operations.
Windowing also lets you compute moving averages and sums on your data, enhancing the
ability to evaluate your data and its impact on your operations.
Programming 859
Appendix: Using OLAP
For each row in a window partition, users can define a window frame, which may vary the
specific range of rows used to perform any computation on the current row of the partition. The
current row provides the reference point for determining the start and end points of the
window frame.
Window specifications can be based on either a physical number of rows using a window
specification that defines a window frame unit of ROWS or a logical interval of a numeric
value, using a window specification that defines a window frame unit of RANGE.
Within OLAP windowing operations, you can use the following functional categories:
• Ranking functions
• Windowing aggregate functions
• Statistical aggregate functions
• Distribution functions
Window Partitioning
Window partitioning is the division of user-specified result sets (input rows) using a
PARTITION BY clause.
A partition is defined by one or more value expressions separated by commas. Partitioned data
is also implicitly sorted and the default sort order is ascending (ASC).
<WINDOW PARTITION CLAUSE> ::=
PARTITION BY <WINDOW PARTITION EXPRESSION LIST>
If a window partition clause is not specified, then the input is treated as single partition.
Note: The term partition as used with analytic functions, refers only to dividing the set of
result rows using a PARTITION BY clause.
A window partition can be defined based on an arbitrary expression. Also, because window
partitioning occurs after GROUPING (if a GROUP BY clause is specified), the result of any
aggregate function, such as SUM, AVG, and VARIANCE, can be used in a partitioning
expression. Therefore, partitions provide another opportunity to perform grouping and
ordering operations in addition to the GROUP BY and ORDER BY clauses; for example, you
can construct queries that compute aggregate functions over aggregate functions, such as the
maximum SUM of a particular quantity.
You can specify a PARTITION BY clause, even if there is no GROUP BY clause.
Window Ordering
Window ordering is the arrangement of results (rows) within each window partition using a
window order clause, which contains one or more value expressions separated by commas.
If a window order clause is not specified, the input rows could be processed in an arbitrary
order.
<WINDOW ORDER CLAUSE> ::= <ORDER SPECIFICATION>
The OLAP window order clause is different from the ORDER BY clause that can be appended
to a nonwindowed query expression.
The ORDER BY clause in an OLAP function, for example, typically defines the expressions
for sorting rows within window partitions; however, you can use the ORDER BY clause
without a PARTITION BY clause, in which case the sort specification ensures that the OLAP
function is applied to a meaningful (and intended) ordering of the intermediate result set.
An order specification is a prerequisite for the ranking family of OLAP functions; it is the
ORDER BY clause, not an argument to the function itself, that identifies the measures for the
ranking values. In the case of OLAP aggregates, the ORDER BY clause is not required in
general, but it is a prerequisite to defining a window frame. This is because the partitioned
rows must be sorted before the appropriate aggregate values can be computed for each frame.
Programming 861
Appendix: Using OLAP
The ORDER BY clause includes semantics for defining ascending and descending sorts, as
well as rules for the treatment of NULL values. By default, OLAP functions assume an
ascending order, where the lowest measured value is ranked 1.
Although this behavior is consistent with the default behavior of the ORDER BY clause that
ends a SELECT statement, it is counterintuitive for most sequential calculations. OLAP
calculations often require a descending order, where the highest measured value is ranked 1;
this requirement must be explicitly stated in the ORDER BY clause with the DESC keyword.
Note: Ranking functions require a <window order clause> because they are defined only over
sorted input. As with an <order by clause> in a <query specification>, the default sort
sequence is ascending.
The use of a <window frame unit> of RANGE also requires the existence of a <window order
clause>. In the case of RANGE, the <window order clause> may only consist of a single
expression.
Window Framing
For nonranking aggregate OLAP functions, you can define a window frame with a window
frame clause, which specifies the beginning and end of the window relative to the current
row.
<WINDOW FRAME CLAUSE> ::=
<WINDOW FRAME UNIT>
<WINDOW FRAME EXTENT>
This OLAP function is computed with respect to the contents of a moving frame rather than
the fixed contents of the whole partition. Depending on its definition, the partition has a start
row and an end row, and the window frame slides from the starting point to the end of the
partition.
Programming 863
Appendix: Using OLAP
specified numeric value. For the RANGE case, the data type of the windowed value must be
comparable to the type of the sort key expression of the ORDER BY clause. There can be only
one sort key expression, and the data type of the sort key expression must allow addition.
The value PRECEDING specifies either the range or number of rows preceding the current
row. If ROWS is specified, then the value is a positive integer indicating a number of rows. If
RANGE is specified, the window includes any rows that are less than the current row minus
the specified numeric value. For the RANGE case, the data type of the windowed value must
be comparable to the type of the sort key expression of the ORDER BY clause. There can be
only one sort key expression, and the data type of the sort key expression must allow
subtraction. This clause cannot be specified in second bound group if the first bound group is
CURRENT ROW or value FOLLOWING.
The combination BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED
FOLLOWING provides an aggregate over an entire partition, without the need to construct a
join to a grouped query. An aggregate over an entire partition is also known as a reporting
aggregate.
When a window frame extent specifies BETWEEN, it explicitly provides the beginning and
end of a window frame.
If the window frame extent specifies only one of these two values then the other value defaults
to CURRENT ROW.
Row-based window frames—In the example rows [1] through [5] represent a partition; each
row becomes the current row as the OLAP window frame slides forward. The frame is defined
as Between Current Row And 2 Following, so each frame includes a maximum of three rows
and a minimum of one row. When the frame reaches the end of the partition, only the current
row is included. The shaded areas indicate which rows are excluded from the frame at each
step.
Programming 865
Appendix: Using OLAP
ROWS
The window frame unit ROWS defines a window in the specified number of rows before or
after the current row, which serves as the reference point that determines the start and end of a
window.
Each analytical calculation is based on the current row within a partition. To produce
determinative results for a window expressed in rows, the ordering expression should be
unique.
The reference point for all window frames is the current row. The SQL/OLAP syntax provides
mechanisms for defining a row-based window frame as any number of rows preceding or
following the current row or preceding and following the current row.
The following list illustrates common examples of a window frame unit:
• Rows between unbounded preceding and current row – specifies a window whose start
point is the beginning of each partition and the end point is the current row and is often used
to construct windows that compute cumulative results, such as cumulative sums.
• Rows between unbounded preceding and unbounded following – specifies a fixed
window, regardless of the current row, over the entire partition. The value of a window
aggregate function is, therefore, identical in each row of the partition.
• Rows between 1 preceding and 1 following – specifies a fixed-sized moving window over
three adjacent rows, one each before and after the current row. You can use this window
frame unit to compute, for example, a 3-day or 3-month moving average.
Be aware of meaningless results that may be generated by gaps in the windowed values
when using ROWS. If the set of values is not continuous, consider using RANGE instead
of ROWS, because a window definition based on RANGE automatically handles adjacent
rows with duplicate values and does not include other rows when there are gaps in the
range.
Note: In the case of a moving window, it is assumed that rows containing NULL values
exist before the first row, and after the last row, in the input. This means that in a 3-row
moving window, the computation for the last row in the input—the current row— includes
the immediately preceding row and a NULL value.
• Rows between current row and current row – restricts the window to the current row only.
• Rows between 1 preceding and 1 preceding – specifies a single row window consisting
only of the preceding row, with respect to the current row. In combination with another
window function that computes a value based on the current row only, this construction
makes it possible to easily compute deltas, or differences in value, between adjacent rows.
RANGE
Range-based window frames—The SQL/OLAP syntax supports another kind of window
frame whose limits are defined in terms of a value-based—or range-based—set of rows, rather
than a specific sequence of rows.
Value-based window frames define rows within a window partition that contain a specific
range of numeric values. The OLAP function’s ORDER BY clause defines the numeric column
to which the range specification is applied, relative to the current row’s value for that column.
The range specification uses the same syntax as the rows specification, but the syntax is
interpreted in a different way.
The window frame unit, RANGE, defines a window frame whose contents are determined by
finding rows in which the ordering column has values within the specified range of value
relative to the current row. This is called a logical offset of a window frame, which you can
specify with constants, such as “3 preceding,” or any expression that can be evaluated to a
numeric constant. When using a window defined with RANGE, there can be only a single
numeric expression in the ORDER BY clause.
Note: ORDER BY key must be a numeric data in RANGE window frame
For example, a frame can be defined as the set of rows with year values some number of years
preceding or following the current row’s year:
ORDER BY year ASC range BETWEEN 1 PRECEDING AND CURRENT ROW
The phrase 1 PRECEDING means the current row’s year value minus 1.
This kind of range specification is inclusive. If the current row’s year value is 2000, all rows in
the window partition with year values 2000 and 1999 qualify for the frame, regardless of the
physical position of those rows in the partition. The rules for including and excluding value-
based rows are quite different from the rules applied to row-based frames, which depend
entirely on the physical sequence of rows.
Put in the context of an OLAP AVG() calculation, the following partial result set further
demonstrates the concept of a value-based window frame. Again, the frame consists of rows
that:
• Have the same year as the current row
• Have the same year as the current row minus 1
Programming 867
Appendix: Using OLAP
If the current row is 1999 and the frame is specified as follows, rows that contain the values
1999 and 1998 (which does not exist in the table) are included in the frame:
ORDER BY year DESC range BETWEEN CURRENT ROW and 1 FOLLOWING
Note: The sort order of the ORDER BY values is a critical part of the test for qualifying rows in
a value-based frame; the numeric values alone do not determine exclusion or inclusion.
Using an unbounded window—The following query produces a result set consisting of all of
the products accompanied by the total quantity of all products:
SELECT id, description, quantity,
SUM(quantity) OVER () AS total
FROM products;
Computing deltas between adjacent rows—Using two windows—one over the current row
and the other over the previous row—provides a direct way of computing deltas, or changes,
between adjacent rows.
SELECT EmployeeID, Surname, SUM(salary)
OVER(ORDER BY BirthDate rows between current row and current row)
AS curr, SUM(Salary)
OVER(ORDER BY BirthDate rows between 1 preceding and 1 preceding)
AS prev, (curr-prev) as delta
FROM Employees
WHERE State IN ('MA', 'AZ', 'CA', 'CO') AND DepartmentID>10
ORDER BY EmployeeID, Surname;
Although the window function SUM() is used, the sum contains only the salary value of either
the current or previous row because of the way the window is specified. Also, the prev value
of the first row in the result is NULL because it has no predecessor; therefore, the delta is
NULL as well.
In each of the examples above, the function used with the OVER() clause is the SUM()
aggregate function.
Programming 869
Appendix: Using OLAP
Window function example—The following example shows a window function. The query
returns a result set that partitions the data by department and then provides a cumulative
summary of employees’ salaries, starting with the employee who has been at the company the
longest. The result set includes only those employees who reside in Massachusetts. The
column sum_salary provides the cumulative total of employees’ salaries.
SELECT DepartmentID, Surname, StartDate, Salary, SUM(Salary) OVER
(PARTITION BY DepartmentID ORDER BY startdate
rows between unbounded preceding and current row)
AS sum_salary FROM Employees
WHERE State IN ('CA') AND DepartmentID IN (100, 200)
ORDER BY DepartmentID;
Ranking Functions
Ranking functions let you compile a list of values from the data set in ranked order, as well as
compose single-statement SQL queries that fulfil requests such as, “Name the top 10 products
shipped this year by total sales,” or “Give the top 5% of salespersons who sold orders to at least
15 different companies.”
SQL/OLAP defines five functions that are categorized as ranking functions:
<RANK FUNCTION TYPE> ::=
RANK | DENSE_RANK | PERCENT_RANK | ROW_NUMBER | NTILE
Ranking functions let you compute a rank value for each row in a result set based on the order
specified in the query. For example, a sales manager might need to identify the top or bottom
sales people in the company, the highest- or lowest-performing sales region, or the best- or
worst-selling products. Ranking functions can provide this information.
RANK
The RANK function returns a number that indicates the rank of the current row among the rows
in the row’s partition, as defined by the ORDER BY clause.
The first row in a partition has a rank of 1, and the last rank in a partition containing 25 rows is
25. RANK is specified as a syntax transformation, which means that an implementation can
choose to actually transform RANK into its equivalent, or it can merely return a result
equivalent to the result that transformation would return.
In the following example, ws1 indicates the window specification that defines the window
named w1.
RANK() OVER ws
is equivalent to:
( COUNT (*) OVER ( ws RANGE UNBOUNDED PRECEDING )
- COUNT (*) OVER ( ws RANGE CURRENT ROW ) + 1 )
The transformation of the RANK function uses logical aggregation (RANGE). As a result, two
or more records that are tied—or have equal values in the ordering column—have the same
rank.The next group in the partition that has a different value has a rank that is more than one
greater than the rank of the tied rows. For example, if there are rows whose ordering column
values are 10, 20, 20, 20, 30, the rank of the first row is 1 and the rank of the second row is 2.
The rank of the third and fourth row is also 2, but the rank of the fifth row is 5. There are no
rows whose rank is 3 or 4. This algorithm is sometimes known as sparse ranking.
Syntax
RANK () OVER ( [ PARTITION BY ] ORDER BY expression [ ASC | DESC ] )
Parameters
Parameter Description
expression A sort specification that can be any valid expres-
sion involving a column reference, aggregates, or
expressions invoking these items.
Returns
INTEGER
Remarks
RANK is a rank analytical function. The rank of row R is defined as the number of rows that
precede R and are not peers of R. If two or more rows are not distinct within the groups
Programming 871
Appendix: Using OLAP
specified in the OVER clause or distinct over the entire result set, then there are one or more
gaps in the sequential rank numbering. The difference between RANK and DENSE_RANK is
that DENSE_RANK leaves no gap in the ranking sequence when there is a tie. RANK leaves a
gap when there is a tie.
RANK requires an OVER (ORDER BY) clause. The ORDER BY clause specifies the parameter
on which ranking is performed and the order in which the rows are sorted in each group. This
ORDER BY clause is used only within the OVER clause and is not an ORDER BY for the
SELECT. No aggregation functions in the rank query are allowed to specify DISTINCT.
The PARTITION BY window partitioning clause in the OVER (ORDER BY) clause is optional.
The ASC or DESC parameter specifies the ordering sequence ascending or descending.
Ascending order is the default.
The OVER clause indicates that the function operates on a query result set. The result set is the
rows that are returned after the FROM, WHERE, GROUP BY, and HAVING clauses have all
been evaluated. The OVER clause defines the data set of the rows to include in the computation
of the rank analytical function.
RANK is allowed only in the select list of a SELECT or INSERT statement or in the ORDER BY
clause of the SELECT statement. RANK can be in a view or a union. The RANK function cannot
be used in a subquery, a HAVING clause, or in the select list of an UPDATE or DELETE
statement. Only one rank analytical function is allowed per query.
Example
This statement illustrates the use of the RANK function:
SELECT Surname, Sex, Salary, RANK() OVER (PARTITION BY Sex
ORDER BY Salary DESC) AS RANK FROM Employees
WHERE State IN ('CA', 'AZ') AND DepartmentID IN (200, 300)
ORDER BY Sex, Salary DESC;
DENSE_RANK
DENSE_RANK returns ranking values without gaps.
The values for rows with ties are still equal, but the ranking of the rows represents the positions
of the clusters of rows having equal values in the ordering column, rather than the positions of
the individual rows. As in the RANK example, where rows ordering column values are 10, 20,
20, 20, 30, the rank of the first row is still 1 and the rank of the second row is still 2, as are the
ranks of the third and fourth rows. The last row, however, is 3, not 5.
DENSE_RANK is computed through a syntax transformation, as well.
DENSE_RANK() OVER ws
is equivalent to:
COUNT ( DISTINCT ROW ( expr_1, . . ., expr_n ) )
OVER ( ws RANGE UNBOUNDED PRECEDING )
In the above example, expr_1 through expr_n represent the list of value expressions in the sort
specification list of window w1.
Syntax
DENSE_RANK () OVER ( ORDER BY expression [ ASC | DESC ] )
Parameters
Table 3. Parameters
Parameter Description
expression A sort specification that can be any valid expres-
sion involving a column reference, aggregates, or
expressions invoking these items.
Returns
INTEGER
Remarks
DENSE_RANK is a rank analytical function. The dense rank of row R is defined as the number
of rows preceding and including R that are distinct within the groups specified in the OVER
clause or distinct over the entire result set. The difference between DENSE_RANK and RANK
is that DENSE_RANK leaves no gap in the ranking sequence when there is a tie. RANK leaves a
gap when there is a tie.
DENSE_RANK requires an OVER (ORDER BY) clause. The ORDER BY clause specifies the
parameter on which ranking is performed and the order in which the rows are sorted in each
Programming 873
Appendix: Using OLAP
group. This ORDER BY clause is used only within the OVER clause and is not an ORDER BY
for the SELECT. No aggregation functions in the rank query are allowed to specify
DISTINCT.
The OVER clause indicates that the function operates on a query result set. The result set is the
rows that are returned after the FROM, WHERE, GROUP BY, and HAVING clauses have all
been evaluated. The OVER clause defines the data set of the rows to include in the computation
of the rank analytical function.
The ASC or DESC parameter specifies the ordering sequence ascending or descending.
Ascending order is the default.
DENSE_RANK is allowed only in the select list of a SELECT or INSERT statement or in the
ORDER BY clause of the SELECT statement. DENSE_RANK can be in a view or a union. The
DENSE_RANK function cannot be used in a subquery, a HAVING clause, or in the select list of
an UPDATE or DELETE statement. Only one rank analytical function is allowed per query.
Example
The following statement illustrates the use of the DENSE_RANK function:
SELECT s_suppkey, DENSE_RANK()
OVER ( ORDER BY ( SUM(s_acctBal) DESC )
AS rank_dense FROM supplier GROUP BY s_suppkey;
PERCENT_RANK
The PERCENT_RANK function calculates a percentage for the rank, rather than a fractional
amount, and returns a decimal value between 0 and 1.
PERCENT_RANK returns the relative rank of a row, which is a number that indicates the
relative position of the current row within the window partition in which it appears. For
example, in a partition that contains 10 rows having different values in the ordering columns,
the third row is given a PERCENT_RANK value of 0.222 …, because you have covered 2/9
(22.222...%) of rows following the first row of the partition. PERCENT_RANK of a row is
defined as one less than the RANK of the row divided by one less than the number of rows in the
partition, as seen in the following example (where “ANT” stands for an approximate numeric
type, such as REAL or DOUBLE PRECISION).
PERCENT_RANK() OVER ws
is equivalent to:
CASE
WHEN COUNT (*) OVER ( ws RANGE BETWEEN UNBOUNDED
PRECEDING AND UNBOUNDED FOLLOWING ) = 1
THEN CAST (0 AS ANT)
ELSE
( CAST ( RANK () OVER ( ws ) AS ANT ) -1 /
( COUNT (*) OVER ( ws RANGE BETWEEN UNBOUNDED
PRECEDING AND UNBOUNDED FOLLOWING ) - 1 )
END
Syntax
PERCENT_RANK () OVER ( ORDER BY expression [ ASC | DESC ] )
Parameters
Parameter Description
expression A sort specification that can be any valid expres-
sion involving a column reference, aggregates, or
expressions invoking these items.
Returns
The PERCENT_RANK function returns a DOUBLE value between 0 and 1.
Remarks
PERCENT_RANK is a rank analytical function. The percent rank of a row R is defined as the
rank of a row in the groups specified in the OVER clause minus one divided by the number of
total rows in the groups specified in the OVER clause minus one. PERCENT_RANK returns a
value between 0 and 1. The first row has a percent rank of zero.
The PERCENT_RANK of a row is calculated as
(Rx - 1) / (NtotalRow - 1)
where Rx is the rank position of a row in the group and NtotalRow is the total number of rows
in the group specified by the OVER clause.
PERCENT_RANK requires an OVER (ORDER BY) clause. The ORDER BY clause specifies the
parameter on which ranking is performed and the order in which the rows are sorted in each
group. This ORDER BY clause is used only within the OVER clause and is not an ORDER BY
Programming 875
Appendix: Using OLAP
for the SELECT. No aggregation functions in the rank query are allowed to specify
DISTINCT.
The OVER clause indicates that the function operates on a query result set. The result set is the
rows that are returned after the FROM, WHERE, GROUP BY, and HAVING clauses have all
been evaluated. The OVER clause defines the data set of the rows to include in the computation
of the rank analytical function.
The ASC or DESC parameter specifies the ordering sequence ascending or descending.
Ascending order is the default.
PERCENT_RANK is allowed only in the select list of a SELECT or INSERT statement or in the
ORDER BY clause of the SELECT statement. PERCENT_RANK can be in a view or a union.
The PERCENT_RANK function cannot be used in a subquery, a HAVING clause, or in the select
list of an UPDATE or DELETE statement. Only one rank analytical function is allowed per
query.
Example
The following statement illustrates the use of the PERCENT_RANK function:
SELECT s_suppkey, SUM(s_acctBal) AS sum_acctBal,
PERCENT_RANK() OVER ( ORDER BY SUM(s_acctBal) DESC )
AS percent_rank_all FROM supplier GROUP BY s_suppkey;
ROW_NUMBER
The ROW_NUMBER function returns a unique row number for each row.
If you define window partitions, ROW_NUMBER starts the row numbering in each partition at
1, and increments each row by 1. If you do not specify a window partition, ROW_NUMBER
numbers the complete result set from 1 to the total cardinality of the table.
The ROW_NUMBER function syntax is:
ROW_NUMBER() OVER ([PARTITION BY window partition] ORDER BY window
ordering)
ROW_NUMBER does not require an argument, but you must specify the parentheses.
The PARTITION BY clause is optional. The OVER (ORDER_BY) clause cannot contain a
window frame ROWS/RANGE specification.
Syntax
ROW_NUMBER() OVER ([PARTITION BY window partition] ORDER BY window
ordering)
Parameters
Parameter Description
window partition (Optional) One or more value expressions sepa-
rated by commas indicating how you want to di-
vide the set of result rows.
Remarks
The ROW_NUMBER function requires an OVER (ORDER_BY) window specification. The
window partitioning clause in the OVER (ORDER_BY) clause is optional. The OVER
(ORDER_BY) clause must not contain a window frame ROWS/RANGE specification.
Example
The following example returns salary data from the Employees table, partitions the result set
by department ID, and orders the data according to employee start date. The ROW_NUMBER
function assigns each row a row number, and restarts the row numbering for each window
partition:
SELECT DepartmentID dID, StartDate, Salary,
ROW_NUMBER()OVER(PARTITION BY dID ORDER BY StartDate) FROM Employees
ORDER BY 1,2;
Programming 877
Appendix: Using OLAP
Ranking Examples
These are some of the ranking functions examples:
Ranking example 1—The SQL query that follows finds the male and female employees from
California, and ranks them in descending order according to salary.
SELECT Surname, Sex, Salary, RANK() OVER (
ORDER BY Salary DESC) as RANK FROM Employees
WHERE State IN ('CA') AND DepartmentID =200
ORDER BY Salary DESC;
Ranking example 2—Using the query from the previous example, you can change the data by
partitioning it by gender. The following example ranks employees in descending order by
salary and partitions by gender:
SELECT Surname, Sex, Salary, RANK() OVER (PARTITION BY Sex
ORDER BY Salary DESC) AS RANK FROM Employees
WHERE State IN ('CA', 'AZ') AND DepartmentID IN (200, 300)
ORDER BY Sex, Salary DESC;
Ranking example 3—This example ranks a list of female employees in California and Texas in
descending order according to salary. The PERCENT_RANK function provides the cumulative
total in descending order.
Ranking example 4—You can use the PERCENT_RANK function to find the top or bottom
percentiles in the data set. This query returns male employees whose salary is in the top five
percent of the data set.
SELECT * FROM (SELECT Surname, Salary, Sex,
CAST(PERCENT_RANK() OVER (ORDER BY salary DESC) as
numeric (4, 2)) AS percent
FROM Employees WHERE State IN ('CA') AND sex ='F' ) AS
DT where percent > 0.5
ORDER BY Salary DESC;
Ranking example 5—This example uses the ROW_NUMBER function to return row numbers
for each row in all window partitions. The query partitions the Employees table by
department ID, and orders the rows in each partition by start date.
SELECT DepartmentID dID, StartDate, Salary ,
ROW_NUMBER()OVER(PARTITION BY dID ORDER BY StartDate)
FROM Employees ORDER BY 1,2;
Programming 879
Appendix: Using OLAP
Windowing aggregate example 1—This query returns a result set, partitioned by year, that
shows a list of the products that sold higher-than-average sales.
SELECT * FROM (SELECT Surname AS E_name, DepartmentID AS
Dept, CAST(Salary AS numeric(10,2) ) AS Sal,
CAST(AVG(Sal) OVER(PARTITION BY DepartmentID) AS
numeric(10, 2)) AS Average, CAST(STDDEV_POP(Sal)
OVER(PARTITION BY DepartmentID) AS numeric(10,2)) AS
STD_DEV
FROM Employees
GROUP BY Dept, E_name, Sal) AS derived_table WHERE
Sal> (Average+STD_DEV )
ORDER BY Dept, Sal, E_name;
For the year 2000, the average number of orders was 1,787. Four products (700, 601, 600, and
400) sold higher than that amount. In 2001, the average number of orders was 1,048 and 3
products exceeded that amount.
Windowing aggregate example 2—This query returns a result set that shows the employees
whose salary is one standard deviation greater than the average salary of their department.
Standard deviation is a measure of how much the data varies from the mean.
SELECT * FROM (SELECT Surname AS E_name, DepartmentID AS
Dept, CAST(Salary AS numeric(10,2) ) AS Sal,
CAST(AVG(Sal) OVER(PARTITION BY dept) AS
numeric(10, 2)) AS Average, CAST(STDDEV_POP(Sal)
OVER(PARTITION BY dept) AS numeric(10,2)) AS
STD_DEV
FROM Employees
GROUP BY Dept, E_name, Sal) AS derived_table WHERE
Sal> (Average+STD_DEV )
ORDER BY Dept, Sal, E_name;
Every department has at least one employee whose salary significantly deviates from the
mean, as shown in these results:
E_name Dept Sal Average STD_DEV
-------- ---- -------- -------- --------
Lull 100 87900.00 58736.28 16829.59
Sheffield 100 87900.00 58736.28 16829.59
Scott 100 96300.00 58736.28 16829.59
Sterling 200 64900.00 48390.94 13869.59
Savarino 200 72300.00 48390.94 13869.59
Kelly 200 87500.00 48390.94 13869.59
Shea 300 138948.00 59500.00 30752.39
Blaikie 400 54900.00 43640.67 11194.02
Morris 400 61300.00 43640.67 11194.02
Evans 400 68940.00 43640.67 11194.02
Martinez 500 55500.80 33752.20 9084.49
Employee Scott earns $96,300.00, while the average salary for department 100 is $58,736.28.
The standard deviation for department 100 is 16,829.00, which means that salaries less than
$75,565.88 (58736.28 + 16829.60 = 75565.88) fall within one standard deviation of the mean.
Programming 881
Appendix: Using OLAP
Correlation
The SQL/OLAP function that computes a correlation coefficient is:
• CORR – returns the correlation coefficient of a set of number pairs.
You can use the CORR function either as a windowing aggregate function (where you specify
a window function type over a window name or specification) or as a simple aggregate
function with no OVER clause.
Covariance
The SQL/OLAP functions that compute covariances include:
• COVAR_POP – returns the population covariance of a set of number pairs.
• COVAR_SAMP – returns the sample covariance of a set of number pairs.
The covariance functions eliminate all pairs where expression1 or expression2 has a null
value.
You can use the covariance functions either as windowing aggregate functions (where you
specify a window function type over a window name or specification) or as simple aggregate
functions with no OVER clause.
Cumulative distribution
The SQL/OLAP function that calculates the relative position of a single value among a group
of rows is CUME_DIST.
The window specification must contain an ORDER_BY clause.
Composite sort keys are not allowed in the CUME_DIST function.
Regression analysis
The regression analysis functions calculate the relationship between an independent variable
and a dependent variable using a linear regression equation. The SQL/OLAP linear regression
functions include:
• REGR_AVGX – computes the average of the independent variable of the regression line.
• REGR_AVGY – computes the average of the dependent variable of the regression line.
• REGR_COUNT – returns an integer representing the number of nonnull number pairs used
to fit the regression line.
• REGR_INTERCEPT – computes the y-intercept of the regression line that best fits the
dependent and independent variables.
• REGR_R2 – computes the coefficient of determination (the goodness-of-fir statistic) for
the regression line.
• REGR_SLOPE – computes the slope of the linear regression line fitted to nonnull pairs.
• REGR_SXX – returns the sum of squares of the independent expressions used in a linear
regression model. Use this function to evaluate the statistical validity of the regression
model.
• REGR_SXY – returns the sum of products of the dependent and independent variables. Use
this function to evaluate the statistical validity of the regression model.
• REGR_SYY – returns values that can evaluate the statistical validity of a regression model.
You can use the regression analysis functions either as windowing aggregate functions (where
you specify a window function type over a window name or specification) or as simple
aggregate functions with no OVER clause.
Programming 883
Appendix: Using OLAP
Inter-Row Functions
The inter-row functions, LAG and LEAD, provide access to previous or subsequent values in a
data series, or to multiple rows in a table.
Inter-row functions also partition simultaneously without a self-join. LAG provides access to
a row at a given physical offset prior to the CURRENT ROW in the table or partition. LEAD
provides access to a row at a given physical offset after the CURRENT ROW in the table or
partition.
LAG and LEAD syntax is identical. Both functions require an OVER (ORDER_BY) window
specification. For example:
LAG (value_expr) [, offset [, default]]) OVER ([PARTITION BY window
partition] ORDER BY window ordering)
and:
LEAD (value_expr) [, offset [, default]]) OVER ([PARTITION BY window
partition] ORDER BY window ordering)
The PARTITION BY clause in the OVER (ORDER_BY) clause is optional. The OVER
(ORDER_BY) clause cannot contain a window frame ROWS/RANGE specification.
value_expr is a table column or expression that defines the offset data to return from the table.
You can define other functions in the value_expr, with the exception of analytic functions.
For both functions, specify the target row by entering a physical offset. The offset value is the
number of rows above or below the current row. Enter a nonnegative numeric data type
(entering a negative value generates an error). If you enter 0, SAP Sybase IQ returns the
current row.
The optional default value defines the value to return if the offset value goes beyond the scope
of the table. The default value of default is NULL. The data type of default must be implicitly
convertible to the data type of the value_expr value, or SAP Sybase IQ generates a conversion
error.
LAG example 1—The inter-row functions are useful in financial services applications that
perform calculations on data streams, such as stock transactions. This example uses the LAG
function to calculate the percentage change in the trading price of a particular stock. Consider
the following trading data from a fictional table called stock_trades:
Note: The fictional stock_trades table is not available in the iqdemo database.
The query partitions the trades by stock symbol, orders them by time of trade, and uses the
LAG function to calculate the percentage increase or decrease in trade price between the
current trade and the previous trade:
select stock_symbol as 'Stock',
traded_at as 'Date/Time of Trade',
trade_price as 'Price/Share',
cast ( ( ( (trade_price
- (lag(trade_price, 1)
over (partition by stock_symbol
order by traded_at)))
/ trade_price)
* 100.0) as numeric(5, 2) )
as '% Price Change vs Previous Price'
from stock_trades
order by 1, 2
The NULL result in the first and fourth output rows indicates that the LAG function is out of
scope for the first row in each of the two partitions. Since there is no previous row to compare
to, SAP Sybase IQ returns NULL as specified by the default variable.
Programming 885
Appendix: Using OLAP
Distribution Functions
SQL/OLAP defines several functions that deal with ordered sets.
The two inverse distribution functions are PERCENTILE_CONT and PERCENTILE_DISC.
These analytical functions take a percentile value as the function argument and operate on a
group of data specified in the WITHIN GROUP clause or operate on the entire data set.
These functions return one value per group. For PERCENTILE_DISC (discrete), the data type
of the results is the same as the data type of its ORDER BY item specified in the WITHIN
GROUP clause. For PERCENTILE_CONT (continuous), the data type of the results is either
numeric, if the ORDER BY item in the WITHIN GROUP clause is a numeric, or double, if the
ORDER BY item is an integer or floating point.
The inverse distribution analytical functions require a WITHIN GROUP (ORDER BY) clause.
For example:
PERCENTILE_CONT ( expression1 )
WITHIN GROUP ( ORDER BY expression2 [ ASC | DESC ] )
The value of expression1 must be a constant of numeric data type and range from 0 to 1
(inclusive). If the argument is NULL, then a “wrong argument for percentile” error is returned.
If the argument value is less than 0, or greater than 1, then a “data value out of range” error is
returned.
The ORDER BY clause, which must be present, specifies the expression on which the
percentile function is performed and the order in which the rows are sorted in each group. This
ORDER BY clause is used only within the WITHIN GROUP clause and is not an ORDER BY for
the SELECT statement.
The WITHIN GROUP clause distributes the query result into an ordered data set from which the
function calculates a result.
The value expression2 is a sort specification that must be a single expression involving a
column reference. Multiple expressions are not allowed and no rank analytical functions, set
functions, or subqueries are allowed in this sort expression.
The ASC or DESC parameter specifies the ordering sequence as ascending or descending.
Ascending order is the default.
Inverse distribution analytical functions are allowed in a subquery, a HAVING clause, a view, or
a union. The inverse distribution functions can be used anywhere the simple nonanalytical
aggregate functions are used. The inverse distribution functions ignore the NULL value in the
data set.
PERCENTILE_CONT example—This example uses the PERCENTILE_CONT function to
determine the 10th percentile value for car sales in a region using the following data set:
sales region dealer_name
----- --------- -----------
900 Northeast Boston
In the following example query, the SELECT statement contains the PERCENTILE_CONT
function:
SELECT region, PERCENTILE_CONT(0.1) WITHIN GROUP
( ORDER BY ProductID DESC )
FROM ViewSalesOrdersSales GROUP BY region;
The result of the SELECT statement lists the 10th percentile value for car sales in a region:
region percentile_cont
--------- ---------------
Canada 601.0
Central 700.0
Eastern 700.0
South 700.0
Western 700.0
In the following query, the SELECT statement contains the PERCENTILE_DISC function:
Programming 887
Appendix: Using OLAP
The result of the SELECT statement lists the 10th percentile value for car sales in each region:
region percentile_cont
--------- ---------------
Northeast 900
Northwest 800
South 500
Syntax
PERCENTILE_CONT ( expression1 )
WITHIN GROUP ( ORDER BY expression2 [ ASC | DESC ] )
Parameters
Parameter Description
expression1 A constant of numeric data type and range from 0
to 1 (inclusive). If the argument is NULL, a
“wrong argument for percentile” error is re-
turned. If the argument value is less than 0 or
greater than 1, a “data value out of range” error is
returned
Remarks
The inverse distribution analytical functions return a k-th percentile value, which can be used
to help establish a threshold acceptance value for a set of data. The function
PERCENTILE_CONT takes a percentile value as the function argument, and operates on a
group of data specified in the WITHIN GROUP clause, or operates on the entire data set. The
function returns one value per group. If the GROUP BY column from the query is not present,
the result is a single row. The data type of the results is the same as the data type of its ORDER
BY item specified in the WITHIN GROUP clause. The data type of the ORDER BY expression
for PERCENTILE_CONT must be numeric.
PERCENTILE_CONT requires a WITHIN GROUP (ORDER BY) clause.
The ORDER BY clause, which must be present, specifies the expression on which the
percentile function is performed and the order in which the rows are sorted in each group. For
the PERCENTILE_CONT function, the data type of this expression must be numeric. This
ORDER BY clause is used only within the WITHIN GROUP clause and is not an ORDER BY for
the SELECT.
The WITHIN GROUP clause distributes the query result into an ordered data set from which the
function calculates a result. The WITHIN GROUP clause must contain a single sort item. If the
WITHIN GROUP clause contains more or less than one sort item, an error is reported.
The ASC or DESC parameter specifies the ordering sequence ascending or descending.
Ascending order is the default.
The PERCENTILE_CONT function is allowed in a subquery, a HAVING clause, a view, or a
union. PERCENTILE_CONT can be used anywhere the simple nonanalytical aggregate
functions are used. The PERCENTILE_CONT function ignores the NULL value in the data
set.
Example
The following example uses the PERCENTILE_CONT function to determine the 10th
percentile value for car sales in a region.
The following data set is used in the example:
sales region dealer_name
900 Northeast Boston
800 Northeast Worcester
800 Northeast Providence
700 Northeast Lowell
540 Northeast Natick
500 Northeast New Haven
450 Northeast Hartford
800 Northwest SF
600 Northwest Seattle
500 Northwest Portland
400 Northwest Dublin
500 South Houston
400 South Austin
300 South Dallas
200 South Dover
Programming 889
Appendix: Using OLAP
The result of the SELECT statement lists the 10th percentile value for car sales in a region:
region percentile_cont
Northeast 840
Northwest 740
South 470
Syntax
PERCENTILE_DISC ( expression1 )
WITHIN GROUP ( ORDER BY expression2 [ ASC | DESC ] )
Parameters
Parameter Description
expression1 A constant of numeric data type and range from 0
to 1 (inclusive). If the argument is NULL, then a
“wrong argument for percentile” error is re-
turned. If the argument value is less than 0 or
greater than 1, then a “data value out of range”
error is returned.
Remarks
The inverse distribution analytical functions return a k-th percentile value, which can be used
to help establish a threshold acceptance value for a set of data. The function
PERCENTILE_DISC takes a percentile value as the function argument and operates on a group
of data specified in the WITHIN GROUP clause or operates on the entire data set. The function
returns one value per group. If the GROUP BY column from the query is not present, the result
is a single row. The data type of the results is the same as the data type of its ORDER BY item
specified in the WITHIN GROUP clause. PERCENTILE_DISC supports all data types that can
be sorted in SAP Sybase IQ.
The ORDER BY clause, which must be present, specifies the expression on which the
percentile function is performed and the order in which the rows are sorted in each group. This
ORDER BY clause is used only within the WITHIN GROUP clause and is not an ORDER BY for
the SELECT.
The WITHIN GROUP clause distributes the query result into an ordered data set from which the
function calculates a result. The WITHIN GROUP clause must contain a single sort item. If the
WITHIN GROUP clause contains more or less than one sort item, an error is reported.
The ASC or DESC parameter specifies the ordering sequence ascending or descending.
Ascending order is the default.
The PERCENTILE_DISC function is allowed in a subquery, a HAVING clause, a view, or a
union. PERCENTILE_DISC can be used anywhere the simple nonanalytical aggregate
functions are used. The PERCENTILE_DISC function ignores the NULL value in the data set.
Example
The following example uses the PERCENTILE_DISC function to determine the 10th percentile
value for car sales in a region.
The following data set is used in the example:
sales region dealer_name
900 Northeast Boston
800 Northeast Worcester
800 Northeast Providence
700 Northeast Lowell
540 Northeast Natick
500 Northeast New Haven
450 Northeast Hartford
800 Northwest SF
600 Northwest Seattle
500 Northwest Portland
400 Northwest Dublin
500 South Houston
400 South Austin
300 South Dallas
200 South Dover
The result of the SELECT statement lists the 10th percentile value for car sales in a region:
Programming 891
Appendix: Using OLAP
region percentile_cont
Northeast 900
Northwest 800
South 500
Numeric Functions
OLAP numeric functions supported by SAP Sybase IQ include CEILING (CEIL is an alias),
EXP (EXPONENTIAL is an alias), FLOOR, LN (LOG is an alias), SQRT, and
WIDTH_BUCKET.
<numeric value function> :: =
<natural logarithm>
| <exponential function>
| <power function>
| <square root>
| <floor function>
| <ceiling function>
| <width bucket function>
• FLOOR – returns the integer value nearest to positive infinity that is not greater than the
value of the argument.
• CEILING – returns the integer value nearest to negative infinity that is not less than the
value of the argument. CEIL is a synonym for CEILING.
WIDTH_BUCKET function
The WIDTH_BUCKET function is somewhat more complicated than the other numeric value
functions. It accepts four arguments: “live value,” two range boundaries, and the number of
equal-sized (or as nearly so as possible) partitions into which the range indicated by the
boundaries is to be divided. WIDTH_BUCKET returns a number indicating the partition into
which the live value should be placed, based on its value as a percentage of the difference
between the higher range boundary and the lower boundary. The first partition is partition
number one.
To avoid errors when the live value is outside the range of boundaries, live values that are less
than the smaller range boundary are placed into an additional first bucket, bucket zero, and live
values that are greater than the larger range boundary are placed into an additional last bucket,
bucket N+1.
WIDTH_BUCKET example
The following example creates a ten-bucket histogram on the credit_limit column for
customers in Massachusetts in the sample table and returns the bucket number (“Credit
Group”) for each customer. Customers with credit limits greater than the maximum value are
assigned to the overflow bucket, 11:
Programming 893
Appendix: Using OLAP
Note: This example is for illustration purposes only and was not generated using the iqdemo
database.
SELECT customer_id, cust_last_name, credit_limit,
WIDTH_BUCKET(credit_limit, 100, 5000, 10) "Credit
Group"
FROM customers WHERE territory = 'MA'
ORDER BY "Credit Group";
CUSTOMER_ID CUST_LAST_NAME CREDIT_LIMIT Credit Group
----------- -------------- ------------ ------------
825 Dreyfuss 500 1
826 Barkin 500 1
853 Palin 400 1
827 Siegel 500 1
843 Oates 700 2
844 Julius 700 2
835 Eastwood 1200 3
840 Elliott 1400 3
842 Stern 1400 3
841 Boyer 1400 3
837 Stanton 1200 3
836 Berenger 1200 3
848 Olmos 1800 4
847 Streep 5000 11
When the bounds are reversed, the buckets are open-closed intervals. For example:
WIDTH_BUCKET (credit_limit, 5000, 0, 5). In this example, bucket number 1 is (4000, 5000],
bucket number 2 is (3000, 4000], and bucket number 5 is (0, 1000]. The overflow bucket is
numbered 0 (5000, +infinity), and the underflow bucket is numbered 6 (-infinity, 0].
Syntax
BIT_LENGTH( column-name )
Parameters
Parameter Description
column-name The name of a column
Returns
INT
Remarks
The return value of a NULL argument is NULL.
The BIT_LENGTH function supports all SAP Sybase IQ data types.
If you are licensed to use the Unstructured Data Analytics functionality, you can use this
function with large object data.
See Function Support in Unstructured Data Analytics.
Syntax
CEIL ( numeric-expression )
Parameters
Parameters Description
expression A column, variable, or expression with a data type
that is either exact numeric, approximate numer-
ic, money, or any type that can be implicitly con-
verted to one of these types. For other data types,
CEIL generates an error. The return value has the
same data type as the value supplied.
Remarks
For a given expression, the CEIL function takes one argument. For example, CEIL (-123.45)
returns -123. CEIL (123.45) returns 124.
Syntax
CEILING ( numeric-expression )
Programming 895
Appendix: Using OLAP
Parameters
Parameter Description
numeric-expression The number whose ceiling is to be calculated.
Returns
DOUBLE
Example
The following statement returns the value 60.00000:
SELECT CEILING( 59.84567 ) FROM iq_dummy
Syntax
EXP ( numeric-expression )
Parameters
Table 5. Parameters
Parameter Description
numeric-expression The exponent.
Returns
DOUBLE
Example
The following statement returns the value 3269017.3724721107:
SELECT EXP( 15 ) FROM iq_dummy
Syntax
FLOOR ( numeric-expression )
Parameters
Table 6. Parameters
Parameter Description
numeric-expression The number, usually a float.
Returns
DOUBLE
Example
The following statement returns the value 123.00:
SELECT FLOOR ( 123 ) FROM iq_dummy
Programming 897
Appendix: Using OLAP
LN Function [Numeric]
Returns the natural logarithm of the specified expression.
Syntax
LN ( numeric-expression )
Parameters
Parameter Description
expression Is a column, variable, or expression with a data
type that is either exact numeric, approximate
numeric, money, or any type that can be implicitly
converted to one of these types. For other data
types, the LN function generates an error. The
return value is of DOUBLE data type.
Remarks
LN takes one argument. For example, LN (20) returns 2.995732.
Syntax
POWER ( numeric-expression1, numeric-expression2 )
Parameters
Parameter Description
numeric-expression1 The base.
Returns
DOUBLE
Remarks
Raises numeric-expression1 to the power numeric-expresson2.
Example
The following statement returns the value 64:
SELECT Power( 2, 6 ) FROM iq_dummy
Syntax
SQRT ( numeric-expression )
Parameters
Parameter Description
numeric-expression The number for which the square root is to be
calculated.
Returns
DOUBLE
Example
The following statement returns the value 3:
SELECT SQRT( 9 ) FROM iq_dummy
Syntax
WIDTH_BUCKET ( expression, min_value, max_value, num_buckets )
Programming 899
Appendix: Using OLAP
Parameters
Parameter Description
expression The expression for which the histogram is being
created. This expression must evaluate to a nu-
meric or datetime value or to a value that can be
implicitly converted to a numeric or datetime
value. If expr evaluates to null, then the expres-
sion returns null.
Remarks
You can generate equiwidth histograms with the WIDTH_BUCKET function. Equiwidth
histograms divide data sets into buckets whose interval size (highest value to lowest value) is
equal. The number of rows held by each bucket will vary. A related function, NTILE, creates
equiheight buckets.
Equiwidth histograms can be generated only for numeric, date or datetime data types;
therefore, the first three parameters should be all numeric expressions or all date expressions.
Other types of expressions are not allowed. If the first parameter is NULL, the result is NULL.
If the second or the third parameter is NULL, an error message is returned, as a NULL value
cannot denote any end point (or any point) for a range in a date or numeric value dimension.
The last parameter (number of buckets) should be a numeric expression that evaluates to a
positive integer value; 0, NULL, or a negative value will result in an error.
Buckets are numbered from 0 to (n+1). Bucket 0 holds the count of values less than the
minimum. Bucket(n+1) holds the count of values greater than or equal to the maximum
specified value.
Example
The following example creates a ten-bucket histogram on the credit_limit column for
customers in Massachusetts in the sample table and returns the bucket number (“Credit
Group”) for each customer. Customers with credit limits greater than the maximum value are
assigned to the overflow bucket, 11:
select EmployeeID, Surname, Salary, WIDTH_BUCKET(Salary, 29000,
60000, 4) "Wages" from Employees where State = 'FL' order by "Wages"
EMPLOYEEID SURNAME SALARY Wages
---------- ------- ------ -----
888 Charlton 28300.000 0
1390 Litton 58930.000 4
207 Francis 53870.000 4
266 Gowda 59840.000 4
445 Lull 87900.000 5
1021 Sterling 64900.000 5
902 Kelly 87500.000 5
1576 Evans 68940.000 5
When the bounds are reversed, the buckets are open-closed intervals. For example:
WIDTH_BUCKET (credit_limit, 5000, 0, 5). In this example, bucket number 1 is (4000, 5000],
bucket number 2 is (3000, 4000], and bucket number 5 is (0, 1000]. The overflow bucket is
numbered 0 (5000, +infinity), and the underflow bucket is numbered 6 (-infinity, 0].
Programming 901
Appendix: Using OLAP
In this example, the computation of the SUM window function occurs after the join of the two
tables and the application of the query’s WHERE clause. The query uses an inline window
specification that specifies that the input rows from the join is processed as follows:
1. Partition (group) the input rows based on the value of the prod_id attribute.
2. Within each partition, sort the rows by the ship_date attribute.
3. For each row in the partition, evaluate the SUM() function over the quantity attribute, using
a sliding window consisting of the first (sorted) row of each partition, up to and including
the current row.
An alternative construction for the query is to specify the window separate from the functions
that use it. This is useful when more than one window function is specified that are based on
the same window. In the case of the query using window functions, a construction that uses the
window clause (declaring a window identified by cumulative) is as follows:
SELECT p.id, p.description, s.quantity, s.shipdate, SUM(s.quantity)
OVER(cumulative ROWS BETWEEN UNBOUNDED PRECEDING and CURRENT ROW )
cumulative FROM SalesOrderItems s JOIN Products p On (s.ProductID
=p.id)WHERE s.shipdate BETWEEN ‘2001-07-01’ and ‘2001-08-31’Window
cumulative as (PARTITION BY s.productid ORDER BY s.shipdate)ORDER BY
p.id;
The window clause appears before the ORDER BY clause in the query specification. When
using a window clause, the following restrictions apply:
Programming 903
Appendix: Using OLAP
Programming 905
Appendix: Using OLAP
20 3 25 25.00
20 4 30 28.33
20 5 31 28.66
20 6 20 27.00
10 1 100 100.00
10 2 120 110.00
10 3 100 106.66
10 4 130 116.66
10 5 120 116.66
10 6 110 120.00
Programming 907
Appendix: Using OLAP
20 4 30 156
20 5 31 156
20 6 20 156
30 1 10 34
30 2 11 34
30 3 12 34
30 4 1 34
Programming 909
Appendix: Using OLAP
Grammar Rule 1
<SELECT LIST EXPRESSION> ::=
<EXPRESSION>
| <GROUP BY EXPRESSION>
| <AGGREGATE FUNCTION>
| <GROUPING FUNCTION>
| <TABLE COLUMN>
| <WINDOWED TABLE FUNCTION>
Grammar Rule 2
<QUERY SPECIFICATION> ::=
<FROM CLAUSE>
[ <WHERE CLAUSE> ]
[ <GROUP BY CLAUSE> ]
[ <HAVING CLAUSE> ]
[ <WINDOW CLAUSE> ]
[ <ORDER BY CLAUSE> ]
Grammar Rule 3
<ORDER BY CLAUSE> ::= <ORDER SPECIFICATION>
Grammar Rule 4
<GROUPING FUNCTION> ::=
GROUPING <LEFT PAREN> <GROUP BY EXPRESSION>
<RIGHT PAREN>
Grammar Rule 5
<WINDOWED TABLE FUNCTION> ::=
<WINDOWED TABLE FUNCTION TYPE> OVER <WINDOW NAME OR
SPECIFICATION>
Grammar Rule 6
<WINDOWED TABLE FUNCTION TYPE> ::=
<RANK FUNCTION TYPE> <LEFT PAREN> <RIGHT PAREN>
| ROW_NUMBER <LEFT PAREN> <RIGHT PAREN>
| <WINDOW AGGREGATE FUNCTION>
Grammar Rule 7
<RANK FUNCTION TYPE> ::=
RANK | DENSE RANK | PERCENT RANK | CUME_DIST
Grammar Rule 8
<WINDOW AGGREGATE FUNCTION> ::=
<SIMPLE WINDOW AGGREGATE FUNCTION>
| <STATISTICAL AGGREGATE FUNCTION>
Grammar Rule 9
<AGGREGATE FUNCTION> ::=
<DISTINCT AGGREGATE FUNCTION>
| <SIMPLE AGGREGATE FUNCTION>
| <STATISTICAL AGGREGATE FUNCTION>
Grammar Rule 10
<DISTINCT AGGREGATE FUNCTION> ::=
<BASIC AGGREGATE FUNCTION TYPE> <LEFT PAREN>
<DISTINCT> <EXPRESSION> <RIGHT PAREN>
| LIST <LEFT PAREN> DISTINCT <EXPRESSION>
[ <COMMA> <DELIMITER> ]
[ <ORDER SPECIFICATION> ] <RIGHT PAREN>
Grammar Rule 11
<BASIC AGGREGATE FUNCTION TYPE> ::=
SUM | MAX | MIN | AVG | COUNT
Grammar Rule 12
<SIMPLE AGGREGATE FUNCTION> ::=
<SIMPLE AGGREGATE FUNCTION TYPE> <LEFT PAREN>
<EXPRESSION> <RIGHT PAREN>
| LIST <LEFT PAREN> <EXPRESSION> [ <COMMA>
<DELIMITER> ]
[ <ORDER SPECIFICATION> ] <RIGHT PAREN>
Grammar Rule 13
<SIMPLE AGGREGATE FUNCTION TYPE> ::= <SIMPLE WINDOW AGGREGATE
FUNCTION TYPE>
Grammar Rule 14
<SIMPLE WINDOW AGGREGATE FUNCTION> ::=
<SIMPLE WINDOW AGGREGATE FUNCTION TYPE> <LEFT PAREN>
<EXPRESSION> <RIGHT PAREN>
| GROUPING FUNCTION
Grammar Rule 15
<SIMPLE WINDOW AGGREGATE FUNCTION TYPE> ::=
<BASIC AGGREGATE FUNCTION TYPE>
| STDDEV | STDDEV_POP | STDDEV_SAMP
| VARIANCE | VARIANCE_POP | VARIANCE_SAMP
Programming 911
Appendix: Using OLAP
Grammar Rule 16
<STATISTICAL AGGREGATE FUNCTION> ::=
<STATISTICAL AGGREGATE FUNCTION TYPE> <LEFT PAREN>
<DEPENDENT EXPRESSION> <COMMA> <INDEPENDENT
EXPRESSION> <RIGHT PAREN>
Grammar Rule 17
<STATISTICAL AGGREGATE FUNCTION TYPE> ::=
CORR | COVAR_POP | COVAR_SAMP | REGR_R2 |
REGR_INTERCEPT | REGR_COUNT | REGR_SLOPE |
REGR_SXX | REGR_SXY | REGR_SYY | REGR_AVGY |
REGR_AVGX
Grammar Rule 18
<WINDOW NAME OR SPECIFICATION> ::=
<WINDOW NAME> | <IN-LINE WINDOW SPECIFICATION>
Grammar Rule 19
<WINDOW NAME> ::= <IDENTIFIER>
Grammar Rule 20
<IN-LINE WINDOW SPECIFICATION> ::= <WINDOW SPECIFICATION>
Grammar Rule 21
<WINDOW CLAUSE> ::= <WINDOW WINDOW DEFINITION LIST>
Grammar Rule 22
<WINDOW DEFINITION LIST> ::=
<WINDOW DEFINITION> [ { <COMMA> <WINDOW DEFINITION>
} . . . ]
Grammar Rule 23
<WINDOW DEFINITION> ::=
<NEW WINDOW NAME> AS <WINDOW SPECIFICATION>
Grammar Rule 24
<NEW WINDOW NAME> ::= <WINDOW NAME>
Grammar Rule 25
<WINDOW SPECIFICATION> ::=
<LEFT PAREN> <WINDOW SPECIFICATION> <DETAILS> <RIGHT
PAREN>
Grammar Rule 26
<WINDOW SPECIFICATION DETAILS> ::=
[ <EXISTING WINDOW NAME> ]
[ <WINDOW PARTITION CLAUSE> ]
[ <WINDOW ORDER CLAUSE> ]
[ <WINDOW FRAME CLAUSE> ]
Grammar Rule 27
<EXISTING WINDOW NAME> ::= <WINDOW NAME>
Grammar Rule 28
<WINDOW PARTITION CLAUSE> ::=
PARTITION BY <WINDOW PARTITION EXPRESSION LIST>
Grammar Rule 29
<WINDOW PARTITION EXPRESSION LIST> ::=
<WINDOW PARTITION EXPRESSION>
[ { <COMMA> <WINDOW PARTITION EXPRESSION> } . . . ]
Grammar Rule 30
<WINDOW PARTITION EXPRESSION> ::= <EXPRESSION>
Grammar Rule 31
<WINDOW ORDER CLAUSE> ::= <ORDER SPECIFICATION>
Grammar Rule 32
<WINDOW FRAME CLAUSE> ::=
<WINDOW FRAME UNIT>
<WINDOW FRAME EXTENT>
Grammar Rule 33
<WINDOW FRAME UNIT> ::= ROWS | RANGE
Grammar Rule 34
<WINDOW FRAME EXTENT> ::= <WINDOW FRAME START> | <WINDOW FRAME
BETWEEN>
Grammar Rule 35
<WINDOW FRAME START> ::=
UNBOUNDED PRECEDING
| <WINDOW FRAME PRECEDING>
| CURRENT ROW
Programming 913
Appendix: Using OLAP
Grammar Rule 36
<WINDOW FRAME PRECEDING> ::= <UNSIGNED VALUE SPECIFICATION>
PRECEDING
Grammar Rule 37
<WINDOW FRAME BETWEEN> ::=
BETWEEN <WINDOW FRAME BOUND 1> AND <WINDOW FRAME
BOUND 2>
Grammar Rule 38
<WINDOW FRAME BOUND 1> ::= <WINDOW FRAME BOUND>
Grammar Rule 39
<WINDOW FRAME BOUND 2> ::= <WINDOW FRAME BOUND>
Grammar Rule 40
<WINDOW FRAME BOUND> ::=
<WINDOW FRAME START>
| UNBOUNDED FOLLOWING
| <WINDOW FRAME FOLLOWING>
Grammar Rule 41
<WINDOW FRAME FOLLOWING> ::= <UNSIGNED VALUE SPECIFICATION>
FOLLOWING
Grammar Rule 42
<GROUP BY EXPRESSION> ::= <EXPRESSION>
Grammar Rule 43
<SIMPLE GROUP BY TERM> ::=
<GROUP BY EXPRESSION>
| <LEFT PAREN> <GROUP BY EXPRESSION> <RIGHT PAREN>
| <LEFT PAREN> <RIGHT PAREN>
Grammar Rule 44
<SIMPLE GROUP BY TERM LIST> ::=
<SIMPLE GROUP BY TERM> [ { <COMMA> <SIMPLE GROUP BY
TERM> } . . . ]
Grammar Rule 45
<COMPOSITE GROUP BY TERM> ::=
<LEFT PAREN> <SIMPLE GROUP BY TERM>
[ { <COMMA> <SIMPLE GROUP BY TERM> } . . . ]
<RIGHT PAREN>
Grammar Rule 46
<ROLLUP TERM> ::= ROLLUP <COMPOSITE GROUP BY TERM>
Grammar Rule 47
<CUBE TERM> ::= CUBE <COMPOSITE GROUP BY TERM>
Grammar Rule 48
<GROUP BY TERM> ::=
<SIMPLE GROUP BY TERM>
| <COMPOSITE GROUP BY TERM>
| <ROLLUP TERM>
| <CUBE TERM>
Grammar Rule 49
<GROUP BY TERM LIST> ::=
<GROUP BY TERM> [ { <COMMA> <GROUP BY TERM> } … ]
Grammar Rule 50
<GROUP BY CLAUSE> ::= GROUP BY <GROUPING SPECIFICATION>
Grammar Rule 51
<GROUPING SPECIFICATION> ::=
<GROUP BY TERM LIST>
| <SIMPLE GROUP BY TERM LIST> WITH ROLLUP
| <SIMPLE GROUP BY TERM LIST> WITH CUBE
Grammar Rule 52
Not supported.
Grammar Rule 53
<ORDER SPECIFICATION> ::= ORDER BY <SORT SPECIFICATION LIST>
<SORT SPECIFICATION LIST> ::= <SORT SPECIFICATION>
[ { <COMMA> <SORT SPECIFICATION> } . . . ]
<SORT SPECIFICATION> ::= <SORT KEY>
[ <ORDERING SPECIFICATION> ] [ <NULL ORDERING> ]
<SORT KEY> ::= <VALUE EXPRESSION>
<ORDERING SPECIFICATION> ::= ASC | DESC
<NULL ORDERING> := NULLS FIRST | NULLS LAST
Programming 915
Appendix: Using OLAP
Default settings
The database options set on connection using TDS include:
Option Set to
allow_nulls_by_default Off
ansinull Off
chained Off
close_on_endtrans Off
date_format YYYY-MM-DD
date_order MDY
escape_character Off
isolation_level 1
on_tsql_error Continue
quoted_identifier Off
time_format HH:NN:SS.SSS
Programming 917
Appendix: Accessing Remote Data
Option Set to
timestamp_format YYYY-MM-DD HH:NN:SS.SSS
tsql_variables On
Note: Do not alter the sp_tsql_environment procedure. It is for system use only.
The procedure sets options only for connections that use the TDS communications protocol.
This includes Sybase Open Client and JDBC connections using jConnect. Other connections
(ODBC and embedded SQL) have the default settings for the database.
Although SAP Sybase IQ allows longer user names and passwords, TDS client names and
passwords cannot exceed 30 bytes. If your password or user ID is longer than 30 bytes,
attempts to connect over TDS (for example, using jConnect) return an invalid user or password
error.
Programming 919
Appendix: Accessing Remote Data
SAODBC
ULODBC
ADSODBC
ASEODBC
DB2ODBC
HANAODBC
IQODBC
MSACCESSODBC
MSSODBC
MYSQLODBC
ODBC
ORAODBC
Note: When using remote data access, if you use an ODBC driver that does not support
Unicode, then character set conversion is not performed on data coming from that ODBC
driver.
The driver used must match the bitness of the database server.
On Windows, you must also define a System Data Source Name (System DSN) with a bitness
matching the database server. For example, use the 32-bit ODBC Data Source Administrator
to create a 32-bit System DSN. A User DSN does not have bitness.
This defines a connection to a database server named TestSA, running on a computer called
myhost, and a database named sample using the TCP/IP protocol.
If you do not specify a database name, the remote connection uses the remote SAP Sybase IQ
server default database.
Programming 921
Appendix: Accessing Remote Data
Notes
• Open Client should be version 11.1.1, EBF 7886 or later. Install Open Client and verify
connectivity to the Adaptive Server Enterprise server before you install ODBC and
configure SAP Sybase IQ. The Sybase ODBC driver should be version 11.1.1, EBF 7911
or later.
• The local setting of the quoted_identifier option controls the use of quoted identifiers for
Adaptive Server Enterprise. For example, if you set the quoted_identifier option to Off
locally, then quoted identifiers are turned off for Adaptive Server Enterprise.
• Configure a user data source in the Configuration Manager with the following attributes:
• General tab – Type any value for Data Source Name. This value is used in the USING
clause of the CREATE SERVER statement.
The server name should match the name of the server in the Sybase interfaces file.
• Advanced tab – Click the Application Using Threads and Enable Quoted
Identifiers options.
• Connection tab – Set the charset field to match your SAP Sybase IQ character set.
Programming 923
Appendix: Accessing Remote Data
Set the language field to your preferred language for error messages.
• Performance tab – Set the Prepare Method to 2-Full.
Set the Fetch Array Size as large as possible for the best performance. This increases
memory requirements since this is the number of rows that must be cached in memory.
Adaptive Server Enterprise recommends using a value of 100.
Set Select Method to 0-Cursor.
Set Packet Size to as large a value as possible. Adaptive Server Enterprise
recommends using a value of -1.
Set Connection Cache to 1.
TINYINT tinyint
SMALLINT smallint
BIGINT numeric(20,0)
DECIMAL(prec,scale) decimal(prec,scale)
NUMERIC(prec,scale) numeric(prec,scale)
SMALLMONEY numeric(10,4)
MONEY numeric(19,4)
REAL real
DOUBLE float
FLOAT(n) float(n)
DATE datetime
TIME datetime
SMALLDATETIME smalldatetime
TIMESTAMP datetime
XML text
ST_GEOMETRY image
UNIQUEIDENTIFIER binary(16)
Example
Supply a connection string in the USING clause of the CREATE SERVER statement to
connect to an Adaptive Server Enterprise database.
CREATE SERVER TestASE
CLASS 'ASEODBC'
USING 'DRIVER=SYBASE ASE ODBC
Driver;Server=TestASE;Port=5000;Database=testdb;UID=username;PWD=pa
ssword'
Programming 925
Appendix: Accessing Remote Data
Notes
• Sybase certifies the use of IBM's DB2 Connect version 5, with fix pack WR09044.
Configure and test your ODBC configuration using the instructions for that product. SAP
Sybase IQ has no specific requirements for the configuration of IBM DB2 data sources.
• The following is an example of a CREATE EXISTING TABLE statement for an IBM DB2
server with an ODBC data source named mydb2:
CREATE EXISTING TABLE ibmcol
AT 'mydb2..sysibm.syscolumns';
TINYINT smallint
SMALLINT smallint
INTEGER int
BIGINT decimal(20,0)
DECIMAL(prec,scale) decimal(prec,scale)
NUMERIC(prec,scale) decimal(prec,scale)
SMALLMONEY decimal(10,4)
MONEY decimal(19,4)
REAL real
DOUBLE float
FLOAT(n) float(n)
DATE date
TIME time
TIMESTAMP timestamp
Notes
• The following is an example of a CREATE EXISTING TABLE statement for an SAP
HANA database server with an ODBC data source named mySAPHANA:
Programming 927
Appendix: Accessing Remote Data
TINYINT TINYINT
SMALLINT SMALLINT
INTEGER INTEGER
BIGINT BIGINT
MONEY DECIMAL(19,4)
REAL REAL
DOUBLE FLOAT
FLOAT(n) FLOAT
DATE DATE
TIME TIME
TIMESTAMP TIMESTAMP
XML BLOB
ST_GEOMETRY BLOB
UNIQUEIDENTIFIER VARBINARY(16)
Access does not support the owner name qualification; leave it empty.
Programming 929
Appendix: Accessing Remote Data
TINYINT TINYINT
SMALLINT SMALLINT
INTEGER INTEGER
BIGINT DECIMAL(19,0)
SMALLMONEY MONEY
MONEY MONEY
REAL REAL
FLOAT(n) FLOAT
DATE DATETIME
TIME DATETIME
TIMESTAMP DATETIME
XML XML
ST_GEOMETRY IMAGE
UNIQUEIDENTIFIER BINARY(16)
Notes
• Versions of Microsoft SQL Server ODBC drivers that have been used are:
• Microsoft SQL Server ODBC Driver Version 06.01.7601
• Microsoft SQL Server Native Client Version 10.00.1600
• The following is an example for Microsoft SQL Server:
CREATE SERVER mysqlserver
CLASS 'MSSODBC'
USING 'DSN=MSSODBC_cli';
Programming 931
Appendix: Accessing Remote Data
TINYINT tinyint
SMALLINT smallint
INTEGER int
BIGINT numeric(20,0)
SMALLMONEY smallmoney
MONEY money
REAL real
DOUBLE float
FLOAT(n) float(n)
TIME datetime
SMALLDATETIME smalldatetime
DATETIME datetime
TIMESTAMP datetime
XML xml
ST_GEOMETRY image
UNIQUEIDENTIFIER binary(16)
Programming 933
Appendix: Accessing Remote Data
Example
Supply a connection string in the USING clause of the CREATE SERVER statement to
connect to a MySQL database.
CREATE SERVER TestMySQL
CLASS 'MYSQLODBC'
USING 'DRIVER=MySQL ODBC 5.1
Driver;DATABASE=mydatabase;SERVER=mySQLHost;UID=me;PWD=secret'
Programming 935
Appendix: Accessing Remote Data
You can import existing sheets into SAP Sybase IQ using CREATE EXISTING, under the
assumption that the first row of your sheet contains column names.
CREATE EXISTING TABLE mywork
AT'excel;d:\\work1;;mywork';
If SAP Sybase IQ reports that the table is not found, you may need to explicitly state the
column and row range you want to map to. For example:
CREATE EXISTING TABLE mywork
AT 'excel;d:\\work1;;mywork$';
Adding the $ to the sheet name indicates that the entire worksheet should be selected.
Note in the location string specified by AT that a semicolon is used instead of a period for field
separators. This is because periods occur in the file names. Excel does not support the owner
name field so leave this blank.
Deletes are not supported. Also some updates may not be possible since the Excel driver does
not support positioned updates.
Example
The following statements create a database server called TestExcel that uses an ODBC DSN to
access the Excel workbook LogFile.xlsx and import its sheet it into SAP Sybase IQ.
CREATE SERVER TestExcel
CLASS 'ODBC'
USING 'DRIVER=Microsoft Excel Driver (*.xls);DBQ=c:\\temp\
\LogFile.xlsx;READONLY=0;DriverID=790'
This statement creates a file named d:\pcdb\fox1.dbf when you choose the Free Table
Directory option in the ODBC Driver Manager.
Notes
• Sybase certifies the use of the Oracle Database version 8.0.03 ODBC driver. Configure
and test your ODBC configuration using the instructions for that product.
• The following is an example of a CREATE EXISTING TABLE statement for an Oracle
Database server named myora:
Programming 937
Appendix: Accessing Remote Data
TINYINT number(3,0)
SMALLINT number(5,0)
INTEGER number(11,0)
BIGINT number(20,0)
DECIMAL(precision, number(precision,
scale) scale)
NUMERIC(precision, number(precision,
scale) scale)
SMALLMONEY numeric(13,4)
MONEY number(19,4)
REAL real
DOUBLE float
FLOAT(n) float
DATE date
TIME date
TIMESTAMP date
UNIQUEIDENTIFI- raw(16)
ER
Example
Supply a connection string in the USING clause of the CREATE SERVER statement to
connect to an Oracle database.
CREATE SERVER TestOracle
CLASS 'ORAODBC'
USING 'DRIVER=Oracle ODBC
Driver;DBQ=mydatabase;UID=username;PWD=password'
Programming 939
Appendix: Accessing Remote Data
Remote Servers
Before remote objects can be mapped to a local proxy table, define the remote server where the
remote object is located.
See also
• CREATE SERVER Statement on page 966
Platform File
HPiUX $IQDIR16/libxx/libdbor-
aodbc12_r.so.1
Linux64 $IQDIR16/libxx/libdbor-
aodbc12_r.so.1
SunOS64 $IQDIR16/libxx/libdbor-
aodbc12_r.so.1
WinAMD64 %$IQDIR16%\bin64\dbor-
aodbc12.dll
Programming 941
Appendix: Accessing Remote Data
Prerequisites
Log in to dbisql or iqisql.
Task
1. Create a server using the data source name from the .odbc.ini file:
CREATE SERVER myora CLASS 'oraodbc' USING 'MyOra2'
2. Create an external login:
CREATE EXTERNLOGIN DBA TO myora REMOTE LOGIN system
IDENTIFIED BY manager
3. Confirm the connection:
sp_remote_tables myora
4. Create a table of Oracle data:
CREATE EXISTING TABLE my_oratable at
'myora..system.oratable'
5. Verify that the connection works by selecting data:
SELECT * FROM my_oratable
Programming 943
Appendix: Accessing Remote Data
• An Enterprise Connect Data Access (ECDA) server named mssql exists on UNIX host
myhostname, port 12530.
• The data is to be retrieved from an MS SQL server named 2000 on host myhostname, port
1433.
1. Configure ASE/CIS with a remote server and proxy to connect via DirectConnect. For
example, use DirectConnect for Oracle to the Oracle server.
2. Configure SAP Sybase IQ with a remote server using the ASEJDBC class to the Adaptive
Server server. (The ASEODBC class is unavailable because there is no 64-bit Unix ODBC
driver for Adaptive Server.)
3. Use the CREATE EXISTING TABLE statement to create proxy tables pointing to the proxy
tables in ASE which in turn point to Oracle.
Querying Remote Data Using DirectConnect and Proxy Table from UNIX
Query data using DirectConnect.
This example shows how to access MS SQL Server data. For this example, assume the
following:
• An SAP Sybase IQ server on host myhostname, port 7594.
• An Adaptive Server server on host myhostname, port 4101.
• An Enterprise Connect Data Access (ECDA) server exists named mssql on host
myhostname, port 12530.
• The data is to be retrieved from an MS SQL server named 2000 on host myhostname, port
1433.
Programming 945
Appendix: Accessing Remote Data
Example
This statement drops the server named RemoteSA:
DROP SERVER RemoteSA;
See also
• DROP SERVER Statement on page 985
See also
• ALTER SERVER Statement on page 961
Prerequisites
None.
Task
Call the sp_remote_tables system procedure to return a list of the tables on a remote server.
If you specify @table_name or @table_owner, the list of tables is limited to only those that
match.
A list of all the tables, or a limited list of tables, is returned.
Programming 947
Appendix: Accessing Remote Data
When using the sp_servercaps system procedure, the server-name specified must be the same
server-name used in the CREATE SERVER statement.
Execute the stored procedure sp_servercaps as follows:
CALL sp_servercaps('server-name');
External Logins
SAP Sybase IQ uses the names and passwords of its clients when it connects to a remote server
on behalf of those clients. However, this behavior can be overridden by creating external
logins.
External logins are alternate login names and passwords that are used when communicating
with a remote server.
When SAP Sybase IQ connects to the remote server, INSERT...LOCATION uses the remote
login for the user ID of the current connection, if a remote login has been created with CREATE
EXTERNLOGIN and the remote server has been defined with a CREATE SERVER statement.
If the remote server is not defined, or a remote login has not been created for the user ID of the
current connection, SAP Sybase IQ connects using the user ID and password of the current
connection.
Note: If you rely on the default user ID and password, and a user changes the password, you
must stop and restart the server before the new password takes effect on the remote server.
Remote logins created with CREATE EXTERNLOGIN are unaffected by changes to the
password for the default user ID.
If you use an integrated login, the SAP Sybase IQ name and password of the SAP Sybase IQ
client is the same as the database login ID and password that the SAP Sybase IQ userid maps to
in syslogins.
Proxy tables
Location transparency of remote data is enabled by creating a local proxy table that maps to
the remote object. You can use a proxy table to access any object (including tables, views, and
materialized views) that the remote database exports as a candidate for a proxy table. Use one
of the following statements to create a proxy table:
• If the table already exists at the remote storage location, use the CREATE EXISTING
TABLE statement. This statement defines the proxy table for an existing table on the
remote server.
• If the table does not exist at the remote storage location, use the CREATE TABLE
statement. This statement creates a new table on the remote server, and also defines the
proxy table for that table.
Note: You cannot modify data in a proxy table when you are within a savepoint.
When a trigger is fired on a proxy table, the permissions used are those of the user who caused
the trigger to fire, not those of the proxy table owner.
• server – This is the name by which the server is known in the current database, as specified
in the CREATE SERVER statement. This field is mandatory for all remote data sources.
• database – The meaning of the database field depends on the data source. Sometimes this
field does not apply and should be left empty. The delimiter is still required, however.
If the data source is Adaptive Server Enterprise, database specifies the database where the
table exists. For example master or pubs2.
If the data source is SAP Sybase IQ, this field does not apply; leave it empty.
If the data source is Excel, Lotus Notes, or Access, you must include the name of the file
containing the table. If the file name includes a period, use the semicolon delimiter.
• owner – If the database supports the concept of ownership, this field represents the owner
name. This field is only required when several owners have tables with the same name.
• table-name – This field specifies the name of the table. For an Excel spreadsheet, this is
the name of the sheet in the workbook. If table-name is left empty, the remote table name is
assumed to be the same as the local proxy table name.
Examples
The following examples illustrate the use of location strings:
• SAP Sybase IQ:
'RemoteSA..GROUPO.Employees'
• Excel:
'RemoteExcel;d:\pcdb\quarter3.xls;;sheet1$'
• Access:
'RemoteAccessDB;\\server1\production\inventory.mdb;;parts'
Programming 949
Appendix: Accessing Remote Data
Prerequisites
You must have the CREATE PROXY TABLE system privilege to create proxy tables owned
by you. You must have the CREATE ANY TABLE or CREATE ANY OBJECT system
privilege to create proxy tables owned by others.
Task
The CREATE TABLE statement creates a new table on the remote server, and defines the
proxy table for that table when you use the AT clause. Columns are defined using SAP Sybase
IQ data types. SAP Sybase IQ automatically converts the data into the remote server's native
types.
If you use the CREATE TABLE statement to create both a local and remote table, and then
subsequently use the DROP TABLE statement to drop the proxy table, the remote table is also
dropped. You can, however, use the DROP TABLE statement to drop a proxy table created
using the CREATE EXISTING TABLE statement. In this case, the remote table is not
dropped.
The CREATE EXISTING TABLE statement creates a proxy table that maps to an existing
table on the remote server. SAP Sybase IQ derives the column attributes and index information
from the object at the remote location.
See also
• CREATE EXISTING TABLE Statement on page 964
• CREATE TABLE Statement on page 968
produces a list of the columns on a remote table and a description of those data types. The
following is the syntax for the sp_remote_columns system procedure:
CALL sp_remote_columns( @server_name, @table_name [, @table_owner [,
@table_qualifier ] ] )
If a table name, owner, or database name is given, the list of columns is limited to only those
that match.
For example, the following returns a list of the columns in the sysobjects table in the
production database on an Adaptive Server Enterprise server named asetest:
CALL sp_remote_columns('asetest, 'sysobjects', null, 'production');
You can use joins between tables on different SAP Sybase IQ databases. The following
example is a simple case using just one database to illustrate the principles.
Example
Perform a join between two remote tables:
1. Create a new database named empty.db.
This database holds no data. It is used only to define the remote objects, and to access the
SAP Sybase IQ sample database.
2. Start a database server running the empty.db. You can do this by running the following
command:
iqsrv16 empty
3. From Interactive SQL, connect to empty.db as user DBA.
4. In the new database, create a remote server named RemoteSA. Its server class is SAODBC,
and the connection string refers to the SAP Sybase IQ 16 Demo ODBC data source:
Programming 951
Appendix: Accessing Remote Data
CLASS 'SAODBC'
USING 'RemoteSA_db3';
4. Create proxy table definitions by executing CREATE EXISTING TABLE statements for
the tables in the other databases you want to access.
CREATE EXISTING TABLE Employees
AT 'remote_db2...Employees';
Example 2
The following statements show a passthrough session with the server named RemoteASE:
FORWARD TO RemoteASE;
SELECT * FROM titles;
SELECT * FROM authors;
FORWARD TO;
Programming 953
Appendix: Accessing Remote Data
Prerequisites
You must have the MANAGE REPLICATION system privilege.
Task
If a remote procedure can return a result set, even if it does not always return one, then the local
procedure definition must contain a RESULT clause.
Remote Transactions
Transaction management involving remote servers uses a two-phase commit protocol.
SAP Sybase IQ implements a strategy that ensures transaction integrity for most scenarios.
If all PREPARE TRANSACTION requests are successful, the server sends a COMMIT
TRANSACTION request to each remote server involved with the transaction.
Any statement preceded by BEGIN TRANSACTION can begin a transaction. Other
statements are sent to a remote server to be executed as a single, remote unit of work.
Internal Operations
This section describes the underlying steps that SAP Sybase IQ performs on remote servers on
behalf of client applications.
Query Parsing
When a statement is received from a client, the database server parses it. The database server
raises an error if the statement is not a valid SQL Anywhere SQL statement.
Query Normalization
In query normalization, referenced objects are verified and data type compatibility is checked.
For example, consider this query:
SELECT *
FROM t1
WHERE c1 = 10
The query normalization stage verifies that table t1 with a column c1 exists in the system
tables. It also verifies that the data type of column c1 is compatible with the value 10. If the
column's data type is DATETIME, for example, this statement is rejected.
Query preprocessing
Query preprocessing prepares the query for optimization. It may change the representation of
a statement so that the SQL statement that SAP Sybase IQ generates for passing to a remote
Programming 955
Appendix: Accessing Remote Data
server is syntactically different from the original statement, even though it is semantically
equivalent.
Preprocessing performs view expansion so that a query can operate on tables referenced by the
view. Expressions may be reordered and subqueries may be transformed to improve
processing efficiency. For example, some subqueries may be converted into joins.
SELECT
SELECT statements are broken down by removing portions that cannot be passed on and
letting SAP Sybase IQ perform the work. For example, suppose a remote server cannot
process the ATAN2 function in the following statement:
SELECT a,b,c
WHERE ATAN2( b, 10 ) > 3
AND c = 10;
Then, SAP Sybase IQ locally applies WHERE ATAN2( b, 10 ) > 3 to the intermediate
result set.
Joins
When a statement contains joins between tables in multiple locations, IQ will attempt to push
joins of collocated tables to the server on which they reside. The results of that join will then be
joined by IQ with results from other remote tables or local tables. IQ will always prefer to push
as much join work as is possible to remote servers. When IQ joins remote tables with local IQ
tables, IQ may choose to use any join algorithm it supports.
The choice of algorithm is based on cost estimates. These algorithms can include nested loop,
hash, or sort-merge joins.
When a nested loop join is chosen between an IQ and a remote table, every effort is made to
make the remote table the outermost table in the join. This is due to the high cost of network
I/O that makes look-ups against a remote table usually much higher than a local table.
Each time a row is found, SAP Sybase IQ would calculate the new value of a and execute:
UPDATE t1
SET a = 'new value'
WHERE CURRENT OF CURSOR;
If a already has a value that equals the new value, a positioned UPDATE would not be
necessary, and would not be sent remotely.
To process an UPDATE or DELETE statement that requires a table scan, the remote data
source must support the ability to perform a positioned UPDATE or DELETE (WHERE
CURRENT OF cursor-name). Some data sources do not support this capability.
Note: Temporary tables cannot be updated
An UPDATE or DELETE cannot be performed if an intermediate temporary table is required.
This occurs in queries with ORDER BY and some queries with subqueries.
Programming 957
Appendix: Accessing Remote Data
Case sensitivity
The case sensitivity setting of your SAP Sybase IQ database should match the settings used by
any remote servers accessed.
SAP Sybase IQ databases are created case insensitive by default. With this configuration,
unpredictable results may occur when selecting from a case-sensitive database. Different
results will occur depending on whether ORDER BY or string comparisons are pushed off to a
remote server, or evaluated by the local SAP Sybase IQ server.
Connectivity tests
Take the following steps to ensure that you can connect to a remote server:
• Make sure that you can connect to a remote server using a client tool such as Interactive
SQL before configuring SAP Sybase IQ.
• Perform a simple passthrough statement to a remote server to check your connectivity and
remote login configuration. For example:
FORWARD TO RemoteSA {SELECT @@version};
• Turn on remote tracing for a trace of the interactions with remote servers. For example:
SET OPTION cis_option = 7;
Once you have turned on remote tracing, the tracing information appears in the database
server messages window. You can log this output to a file by specifying the -o server option
when you start the database server.
Programming 959
Appendix: Accessing Remote Data
Syntax
ALTER SERVER server-name
[ CLASS 'server-class' ]
[ USING 'connection-info' ]
[ CAPABILITY 'cap-name' { ON | OFF } ]
[ CONNECTION CLOSE [ CURRENT | ALL | connection-id ] ]
Parameters
(back to top) on page 961
• cap-name – the name of a server capability
• CLASS – changes the server class.
Programming 961
Appendix: SQL Reference
You can close both ODBC and JDBC connections to a remote server using this syntax. You
do not need the SERVER OPERATOR system privilege to execute either of these
statements.
You can also disconnect a specific remote ODBC connection by specifying a connection
ID, or disconnect all remote ODBC connections by specifying the ALL keyword. If you
attempt to close a JDBC connection by specifying the connection ID or the ALL keyword,
an error occurs. When the connection identified by connection-id is not the current local
connection, the user must have the SERVER OPERATOR system privilege to be able to
close the connection.
Examples
(back to top) on page 961
• Example 1 – changes the server class of the Adaptive Server server named ase_prod so
its connection to SAP Sybase IQ is ODBC-based. The Data Source Name is
ase_prod.
ALTER SERVER ase_prod
CLASS 'ASEODBC'
USING 'ase_prod'
• Example 2 – changes a capability of server infodc:
ALTER SERVER infodc
CAPABILITY 'insert select' OFF
• Example 3 – closes all connections to the remote server named rem_test:
ALTER SERVER rem_test
CONNECTION CLOSE ALL
• Example 4 – closes the connection to the remote server named rem_test that has the
connection ID 142536:
ALTER SERVER rem_test
CONNECTION CLOSE 142536
Usage
(back to top) on page 961
Side effects:
• Automatic commit
Standards
(back to top) on page 961
• SQL—Vendor extension to ISO/ANSI SQL grammar.
• SAP Sybase Database product—Supported by Open Client/Open Server.
Permissions
(back to top) on page 961
Requires the SERVER OPERATOR system privilege.
Programming 963
Appendix: SQL Reference
Syntax
CREATE EXISTING TABLE [owner.]table_name
[ ( column-definition, … ) ]
AT 'location-string'
Parameters
(back to top) on page 964
• column-definition – if you do not specify column definitions, SAP Sybase IQ derives the
column list from the metadata it obtains from the remote table. If you do specify column
definitions, SAP Sybase IQ verifies them. When SAP Sybase IQ checks column names,
data types, lengths, and null properties:
• Column names must match identically (although case is ignored).
• Data types in CREATE EXISTING TABLE must match or be convertible to the data types
of the column on the remote location. For example, a local column data type is defined
as NUMERIC, whereas the remote column data type is MONEY. You may encounter
some errors, if you select from a table in which the data types do not match or other
inconsistencies exist.
• Each column’s NULL property is checked. If the local column’s NULL property is not
identical to the remote column’s NULL property, a warning message is issued, but the
statement is not aborted.
• Each column’s length is checked. If the lengths of CHAR, VARCHAR, BINARY,
DECIMAL, and NUMERIC columns do not match, a warning message is issued, but the
command is not aborted. You might choose to include only a subset of the actual
remote column list in your CREATE EXISTING statement.
• AT – specifies the location of the remote object. The AT clause supports the semicolon (;)
as a delimiter. If a semicolon is present anywhere in the location string, the semicolon is the
field delimiter. If no semicolon is present, a period is the field delimiter. This allows you to
use file names and extensions in the database and owner fields. Semicolon field delimiters
are used primarily with server classes that are not currently supported; however, you can
also use them where a period would also work as a field delimiter.
For example, this statement maps the table proxy_a1 to the SQL Anywhere database
mydb on the remote server myasa:
CREATE EXISTING TABLE
proxy_a1
AT 'myasa;mydb;;a1'
Examples
(back to top) on page 964
• Example 1 – create a proxy table named nation for the nation table at the remote
server server_a:
CREATE EXISTING TABLE nation
( n_nationkey int,
n_name char(25),
n_regionkey int,
n_comment char(152))
AT 'server_a.db1.joe.nation'
• Example 2 – create a proxy table named blurbs for the blurbs table at the remote
server server_a. SAP Sybase IQ derives the column list from the metadata it obtains
from the remote table:
CREATE EXISTING TABLE blurbs
AT 'server_a.db1.joe.blurbs'
• Example 3 – create a proxy table named rda_employee for the Employees table at
the SAP Sybase IQ remote server remote_iqdemo_srv:
CREATE EXISTING TABLE rda_employee
AT 'remote_iqdemo_srv..dba.Employees'
Usage
(back to top) on page 964
CREATE EXISTING TABLE is a variant of the CREATE TABLE statement. The EXISTING
keyword is used with CREATE TABLE to specify that a table already exists remotely, and that
its metadata is to be imported into SAP Sybase IQ. This establishes the remote table as a
Programming 965
Appendix: SQL Reference
visible entity to its users. SAP Sybase IQ verifies that the table exists at the external location
before it creates the table.
Tables used as proxy tables cannot have names longer than 30 characters.
If the object does not exist (either as a host data file or remote server object), the statement is
rejected with an error message.
Index information from the host data file or remote server table is extracted and used to create
rows for the system table sysindexes. This defines indexes and keys in server terms and
enables the query optimizer to consider any indexes that might exist on this table.
Referential constraints are passed to the remote location when appropriate.
In a simplex environment, you cannot create a proxy table that refers to a remote table on the
same node. In a multiplex environment, you cannot create a proxy table that refers to the
remote table defined within the multiplex.
For example, in a simplex environment, if you try to create proxy table proxy_e, which
refers to base table Employees defined on the same node, the CREATE EXISTING TABLE
statement is rejected with an error message. In a multiplex environment, the CREATE
EXISTING TABLE statement is rejected if you create proxy table proxy_e from any node
(coordinator or secondary) that refers to remote table Employees defined within a
multiplex.
Standards
(back to top) on page 964
• SQL—ISO/ANSI SQL compliant.
• SAP Sybase Database product—Supported by Open Client/Open Server.
Permissions
(back to top) on page 964
For table to be owned by self – Requires one of:
• CREATE ANY TABLE system privilege.
• CREATE ANY OBJECT system privilege.
For table to be owned by any user – Requires the CREATE ANY TABLE system privilege.
Syntax
CREATE SERVER server-name
CLASS 'server-class'
USING 'connection-info'
[ READ ONLY ]
Parameters
(back to top) on page 966
• USING – if a JDBC-based server class is used, the USING clause is hostname:port-
number [/dbname] where:
• hostname – the machine on which the remote server runs.
• portnumber – the TCP/IP port number on which the remote server listens. The default
port number for SAP Sybase IQ and SAP Sybase SQL Anywhere® is 2638.
• dbname – for SQL Anywhere remote servers, if you do not specify a dbname, the
default database is used. For Adaptive Server, the default is the master database, and an
alternative to using dbname is to another database by some other means (for example,
in the FORWARD TO statement).
If an ODBC-based server class is used, the USING clause is the data-source-name, which
is the ODBC Data Source Name.
• READ ONLY – specifies that the remote server is a read-only data source. Any update
request is rejected by SAP Sybase IQ.
Examples
(back to top) on page 966
Programming 967
Appendix: SQL Reference
• Example 1 – create a remote server for the JDBC-based Adaptive Server server named
ase_prod. Its machine name is “banana” and port number is 3025.
CREATE SERVER ase_prod
CLASS 'asejdbc'
USING 'banana:3025'
• Example 2 – create an SQL Anywhere remote server named testasa on the machine
“apple” with listening on port number 2638:
CREATE SERVER testasa
CLASS 'asajdbc'
USING 'apple:2638'
• Example 3 – create a remote server for the Oracle server named oracle723. Its ODBC
Data Source Name is “oracle723”:
CREATE SERVER oracle723
CLASS 'oraodbc'
USING 'oracle723'
Usage
(back to top) on page 966
CREATE SERVER defines a remote server from the SAP Sybase IQ catalogs.
Side Effects
• Automatic commit
Standards
(back to top) on page 966
• SQL—ISO/ANSI SQL compliant.
• SAP Sybase Database product—Supported by Open Client/Open Server.
Permissions
(back to top) on page 966
Requires the SERVER OPERATOR system privilege.
Syntax
CREATE [ { GLOBAL | LOCAL } TEMPORARY ] TABLE
[ IF NOT EXISTS ] [ owner. ]table-name
… ( column-definition [ column-constraint ] …
[ , column-definition [ column-constraint ] …]
[ , table-constraint ] … )
|{ ENABLE | DISABLE } RLV STORE
…[ IN dbspace-name ]
…[ ON COMMIT { DELETE | PRESERVE } ROWS ]
[ AT location-string ]
[PARTITION BY
range-partitioning-scheme
| hash-partitioning-scheme
| composite-partitioning-scheme ]
Programming 969
Appendix: SQL Reference
| PRIMARY KEY
| REFERENCES table-name [ ( column-name ) ] [ action ]
}
[ IN dbspace-name ]
| CHECK ( condition )
| IQ UNIQUE ( integer )
}
Parameters
(back to top) on page 968
A BIT data type column cannot be explicitly placed in a dbspace. The following is not
supported for BIT data types:
CREATE TABLE t1(c1_bit bit IN iq_main);
• ON COMMIT – allowed for temporary tables only. By default, the rows of a temporary
table are deleted on COMMIT.
• AT – creates a proxy table that maps to a remote location specified by the location-string
clause. Proxy table names must be 30 characters or less. The AT clause supports semicolon
(;) delimiters. If a semicolon is present anywhere in the location-string clause, the
semicolon is the field delimiter. If no semicolon is present, a period is the field delimiter.
This allows file names and extensions to be used in the database and owner fields.
Semicolon field delimiters are used primarily with server classes not currently supported;
however, you can also use them in situations where a period would also work as a field
delimiter. For example, this statement maps the table proxy_a to the SQL Anywhere
database mydb on the remote server myasa:
CREATE TABLE proxy_a1
AT 'myasa;mydb;;a1'
Programming 971
Appendix: SQL Reference
• IF NOT EXISTS – if the named object already exists, no changes are made and an error is
not returned.
• { ENABLE | DISABLE } RLV STORE – registers this table with the RLV store for real-
time in-memory updates. Not supported for IQ temporary tables. This value overrides the
value of the database option BASE_TABLES_IN_RLV. Requires the CREATE TABLE
system privilege and CREATE permissions on the RLV store dbspace to set this value to
ENABLE.
• column-definition – defines a table column. Allowable data types are described in
Reference: Building Blocks, Tables, and Procedures >SQL Data Types. Two columns in
the same table cannot have the same name. You can create up to 45,000 columns; however,
there might be performance penalties in tables with more than 10,000 columns.
• [ NOT ] NULL ] – includes or excludes NULL values. If NOT NULL is specified, or if
the column is in a UNIQUE or PRIMARY KEY constraint, the column cannot contain
any NULL values. The limit on the number of columns per table that allow NULLs is
approximately 8*(database-page-size - 30).
• DEFAULT default-value – specify a default column value with the DEFAULT
keyword in the CREATE TABLE (and ALTER TABLE) statement. A DEFAULT value
is used as the value of the column in any INSERT (or LOAD) statement that does not
specify a column value.
• DEFAULT AUTOINCREMENT – the value of the DEFAULT AUTOINCREMENT
column uniquely identifies every row in a table. Columns of this type are also known as
IDENTITY columns, for compatibility with Adaptive Server. The IDENTITY/
DEFAULT AUTOINCREMENT column stores sequential numbers that are
automatically generated during inserts and updates. When using IDENTITY or
DEFAULT AUTOINCREMENT, the column must be one of the integer data types, or
an exact numeric type, with scale 0. The column value might also be NULL. You must
qualify the specified table name with the owner name.
ON inserts into the table. If a value is not specified for the IDENTITY/DEFAULT
AUTOINCREMENT column, a unique value larger than any other value in the column
is generated. If an INSERT specifies a value for the column, it is used; if the specified
value is not larger than the current maximum value for the column, that value is used as
a starting point for subsequent inserts.
Deleting rows does not decrement the IDENTITY/AUTOINCREMENT counter.
Gaps created by deleting rows can only be filled by explicit assignment when using an
insert. The database option IDENTITY_INSERT must be set to the table name to
perform an insert into an IDENTITY/AUTOINCREMENT column.
For example, this creates a table with an IDENTITY column and explicitly adds some
data to it:
CREATE TABLE mytable(c1 INT IDENTITY);
SET TEMPORARY OPTION IDENTITY_INSERT = "DBA".mytable;
INSERT INTO mytable VALUES(5);
After an explicit insert of a row number less than the maximum, subsequent rows
without explicit assignment are still automatically incremented with a value of one
greater than the previous maximum.
You can find the most recently inserted value of the column by inspecting the
@@identity global variable.
• IDENTITY – a Transact-SQL® -compatible alternative to using the
AUTOINCREMENT default. In SAP Sybase IQ, the identity column may be created
using either the IDENTITY or the DEFAULT AUTOINCREMENT clause.
• table-constraint – helps ensure the integrity of data in the database. There are four types
of integrity constraints:
• UNIQUE – identifies one or more columns that uniquely identify each row in the table.
No two rows in the table can have the same values in all the named columns. A table
may have more than one unique constraint.
• PRIMARY KEY – the same as a UNIQUE constraint except that a table can have only
one primary-key constraint. You cannot specify the PRIMARY KEY and UNIQUE
constraints for the same column. The primary key usually identifies the best identifier
for a row. For example, the customer number might be the primary key for the customer
table.
• FOREIGN KEY – restricts the values for a set of columns to match the values in a
primary key or uniqueness constraint of another table. For example, a foreign-key
constraint could be used to ensure that a customer number in an invoice table
corresponds to a customer number in the customer table.
You cannot create foreign-key constraints on local temporary tables. Global temporary
tables must be created with ON COMMIT PRESERVE ROWS.
• CHECK – allows arbitrary conditions to be verified. For example, a check constraint
could be used to ensure that a column called Gender contains only the values male or
female. No row in a table is allowed to violate a constraint. If an INSERT or UPDATE
statement would cause a row to violate a constraint, the operation is not permitted and
the effects of the statement are undone.
Column identifiers in column check constraints that start with the symbol ‘@’ are
placeholders for the actual column name. A statement of the form:
CREATE TABLE t1(c1 INTEGER CHECK (@foo < 5))
Column identifiers appearing in table check constraints that start with the symbol
‘@’are not placeholders.
If a statement would cause changes to the database that violate an integrity constraint, the
statement is effectively not executed and an error is reported. (Effectively means that any
changes made by the statement before the error was detected are undone.)
Programming 973
Appendix: SQL Reference
Column constraints are normally used unless the constraint references more than one
column in the table. In these cases, a table constraint must be used.
• IQ UNIQUE – defines the expected cardinality of a column and determines whether
the column loads as Flat FP or NBit FP. An IQ UNIQUE(n) value explicitly set to 0
loads the column as Flat FP. Columns without an IQ UNIQUE constraint implicitly
load as NBit up to the limits defined by the FP_NBIT_AUTOSIZE_LIMIT,
FP_NBIT_LOOKUP_MB, and FP_NBIT_ROLLOVER_MAX_MB options:
• FP_NBIT_AUTOSIZE_LIMIT limits the number of distinct values that load as
NBit
• FP_NBIT_LOOKUP_MB sets a threshold for the total NBit dictionary size
• FP_NBIT_ROLLOVER_MAX_MB sets the dictionary size for implicit NBit
rollovers from NBit to Flat FP
• FP_NBIT_ENFORCE_LIMITS enforces NBit dictionary sizing limits. This
option is OFF by default
Using IQ UNIQUE with an n value less than the FP_NBIT_AUTOSIZE_LIMIT is not
necessary. Auto-size functionality automatically sizes all low or medium cardinality
columns as NBit. Use IQ UNIQUE in cases where you want to load the column as Flat
FP or when you want to load a column as NBit when the number of distinct values
exceeds the FP_NBIT_AUTOSIZE_LIMIT.
Note:
• Consider memory usage when specifying high IQ UNIQUE values. If machine
resources are limited, avoid loads with FP_NBIT_ENFORCE_LIMITS='OFF'
(default).
Prior to SAP Sybase IQ 16.0, an IQ UNIQUE n value > 16777216 would rollover to
Flat FP. In 16.0, larger IQ UNIQUE values are supported for tokenization, but may
require significant memory resource requirements depending on cardinality and
column width.
• BIT, BLOB,and CLOB data types do not support NBit dictionary compression. If
FP_NBIT_IQ15_COMPATIBILITY=’OFF’, a non-zero IQ UNIQUE column
specification in a CREATE TABLE or ALTER TABLE statement that includes these
data types returns an error.
Programming 975
Appendix: SQL Reference
foreign-key columns have the same names as the columns in the primary table. If
foreign-key column names are specified, then the primary key column names must be
specified, and the column names are paired according to position in the lists.
If the primary table is not the same as the foreign-key table, either the unique or
primary key constraint must have been defined on the referenced key. Both referenced
key and foreign key must have the same number of columns, of identical data type with
the same sign, precision, and scale.
The value of the row's foreign key must appear as a candidate key value in one of the
primary table's rows unless one or more of the columns in the foreign key contains nulls
in a null allows foreign key column.
Any foreign-key column not explicitly defined is automatically created with the same
data type as the corresponding column in the primary table. These automatically
created columns cannot be part of the primary key of the foreign table. Thus, a column
used in both a primary key and foreign key must be explicitly created.
role-name is the name of the foreign key. The main function of role-name is to
distinguish two foreign keys to the same table. If no role-name is specified, the role
name is assigned as follows:
1. If there is no foreign key with a role-name the same as the table name, the table
name is assigned as the role-name.
2. If the table name is already taken, the role-name is the table name concatenated
with a zero-padded 3-digit number unique to the table.
The referential integrity action defines the action to be taken to maintain foreign-key
relationships in the database. Whenever a primary key value is changed or deleted from
a database table, there may be corresponding foreign key values in other tables that
should be modified in some way. You can specify an ON DELETE clause, followed by
the RESTRICT clause.
• RESTRICT – generates an error if you try to update or delete a primary key value
while there are corresponding foreign keys elsewhere in the database. Generates an
error if you try to update a foreign key so that you create new values unmatched by a
candidate key. This is the default action, unless you specify that LOAD optionally
reject rows that violate referential integrity. This enforces referential integrity at the
statement level.
If you use CHECK ON COMMIT without specifying any actions, then RESTRICT is
implied as an action for DELETE. SAP Sybase IQ does not support CHECK ON
COMMIT.
a global temporary table cannot have a foreign key that references a base table and a
base table cannot have a foreign key that references a global temporary table. Local
temporary tables cannot have or be referenced by a foreign key.
The partition-name is the name of a new partition on which table rows are stored. Partition
names must be unique within the set of partitions on a table. The partition-name is
required.
• VALUE – specifies the inclusive upper bound for each partition (in ascending order).
The user must specify the partitioning criteria for each range partition to guarantee that
Programming 977
Appendix: SQL Reference
each row is distributed to only one partition. NULLs are allowed for the partition
column and rows with NULL as partition key value belong to the first table partition.
However, NULL cannot be the bound value.
There is no lower bound (MIN value) for the first partition. Rows of NULL cells in the
first column of the partition key will go to the first partition. For the last partition, you
can either specify an inclusive upper bound or MAX. If the upper bound value for the
last partition is not MAX, loading or inserting any row with partition key value larger
than the upper bound value of the last partition generates an error.
• Max – denotes the infinite upper bound and can only be specified for the last partition.
• IN – specifies the dbspace in the partition-decl on which rows of the partition should
reside.
These restrictions affect partitions keys and bound values for range partitioned tables:
• Partition bounds must be constants, not constant expressions.
• Partition bounds must be in ascending order according to the order in which the
partitions were created. That is, the upper bound for the second partition must be higher
than for the first partition, and so on.
In addition, partition bound values must be compatible with the corresponding
partition-key column data type. For example, VARCHAR is compatible with CHAR.
• If a bound value has a different data type than that of its corresponding partition key
column, SAP Sybase IQ converts the bound value to the data type of the partition key
column, with these exceptions:
• Explicit conversions are not allowed. This example attempts an explicit conversion
from INT to VARCHAR and generates an error:
CREATE TABLE Employees(emp_name VARCHAR(20))
PARTITION BY RANGE(emp_name)
(p1 VALUES <=(CAST (1 AS VARCHAR(20))),
p2 VALUES <= (CAST (10 AS VARCHAR(20)))
• Implicit conversions that result in data loss are not allowed. In this example, the
partition bounds are not compatible with the partition key type. Rounding assumptions
may lead to data loss and an error is generated:
CREATE TABLE emp_id (id INT) PARTITION BY RANGE(id) (p1 VALUES
<= (10.5), p2 VALUES <= (100.5))
• In this example, the partition bounds and the partition key data type are compatible.
The bound values are directly converted to float values. No rounding is required, and
conversion is supported:
CREATE TABLE id_emp (id FLOAT)
PARTITION BY RANGE(id) (p1 VALUES <= (10),
p2 VALUES <= (100))
• Conversions from non-binary data types to binary data types are not allowed. For
example, this conversion is not allowed and returns an error:
CREATE TABLE newemp (name BINARY)
PARTITION BY RANGE(name)
• Restrictions –
• You can only hash partition a base table. Attempting to partitioning a global
temporary table or a local temporary table raises an error.
• You cannot add, drop, merge, or split a hash partition.
• You cannot add or drop a column from a hash partition key.
• PARTITION BY HASH RANGE – subpartitions a hash-partitioned table by range. In a
hash-range-partitioning-scheme declaration, a SUBPARTITION BY RANGE clause adds
a new range subpartition to an existing hash-range partitioned table:
hash-range-partitioning-scheme:
PARTITION BY HASH ( partition-key [ , partition-key, … ] )
[ SUBPARTITION BY RANGE ( range-partition-decl [ , range-
partition-decl ... ] ) ]
The hash partition specifies how the data is logically distributed and colocated; the range
subpartition specifies how the data is physically placed. The new range subpartition is
logically partitioned by hash with the same hash partition keys as the existing hash-range
partitioned table. The range subpartition key is restricted to one column.
• Restrictions –
• You can only hash partition a base table. Attempting to partitioning a global
temporary table or a local temporary table raises an error.
• You cannot add, drop, merge, or split a hash partition.
• You cannot add or drop a column from a hash partition key.
Programming 979
Appendix: SQL Reference
Examples
(back to top) on page 968
• Example 1 – create a table named SalesOrders2 with five columns. Data pages for
columns FinancialCode, OrderDate, and ID are in dbspace Dsp3. Data pages for
integer column CustomerID are in dbspace Dsp1. Data pages for CLOB column
History are in dbspace Dsp2. Data pages for the primary key, HG for ID, are in dbspace
Dsp4:
CREATE TABLE SalesOrders2 (
FinancialCode CHAR(2),
CustomerID int IN Dsp1,
History CLOB IN Dsp2,
OrderDate TIMESTAMP,
ID BIGINT,
PRIMARY KEY(ID) IN Dsp4
) IN Dsp3
• Example 2 – create a table fin_code2 with four columns. Data pages for columns
code, type, and id are in the default dbspace, which is determined by the value of the
database option DEFAULT_DBSPACE. Data pages for CLOB column description
are in dbspace Dsp2. Data pages from foreign key fk1, HG for c1 are in dbspace Dsp4:
CREATE TABLE fin_code2 (
code INT,
type CHAR(10),
description CLOB IN Dsp2,
id BIGINT,
FOREIGN KEY fk1(id) REFERENCES SalesOrders(ID) IN Dsp4
)
• Example 3 – create a table t1 where partition p1 is adjacent to p2 and partition p2 is
adjacent to p3:
CREATE TABLE t1 (c1 INT, c2 INT)
PARTITION BY RANGE(c1)
(p1 VALUES <= (0), p2 VALUES <= (10), p3 VALUES <= (100))
• Example 4 – create a RANGE partitioned table bar with six columns and three partitions,
mapping data to partitions based on dates:
CREATE TABLE bar (
c1 INT IQ UNIQUE(65500),
c2 VARCHAR(20),
c3 CLOB PARTITION (P1 IN Dsp11, P2 IN Dsp12,
P3 IN Dsp13),
c4 DATE,
c5 BIGINT,
c6 VARCHAR(500) PARTITION (P1 IN Dsp21,
P2 IN Dsp22),
PRIMARY KEY (c5) IN Dsp2) IN Dsp1
PARTITION BY RANGE (c4)
(P1 VALUES <= ('2006/03/31') IN Dsp31,
P2 VALUES <= ('2006/06/30') IN Dsp32,
• Example 5 – create a HASH partitioned (table tbl42) that includes a PRIMARY KEY
(column c1) and a HASH PARTITION KEY (columns c4 and c3).
CREATE TABLE tbl42 (
c1 BIGINT NOT NULL,
c2 CHAR(2) IQ UNIQUE(50),
c3 DATE IQ UNIQUE(36524),
c4 VARCHAR(200),
PRIMARY KEY (c1)
)
PARTITION BY HASH ( c4, c3 )
• Example 6 – create a hash-ranged partitioned table with a PRIMARY KEY (column c1), a
hash partition key (columns c4 and c2) and a range subpartition key (column c3).
CREATE TABLE tbl42 (
c1 BIGINT NOT NULL,
c2 CHAR(2) IQ UNIQUE(50),
c3 DATE,
c4 VARCHAR(200),
PRIMARY KEY (c1)) IN Dsp1
Programming 981
Appendix: SQL Reference
The example creates tab1 in the IQ_SYSTEM_TEMP dbspace in the following cases:
• DQP_ENABLED logical server policy option is set ON but there are no read-write files
in IQ_SHARED_TEMP
• DQP_ENABLED option is OFF, TEMP_DATA_IN_SHARED_TEMP logical server
policy option is ON, but there are no read-write files in IQ_SHARED_TEMP
• Both the DQP_ENABLED option and the TEMP_DATA_IN_SHARED_TEMP option
are set OFF
The example creates the same table tab1 in the IQ_SHARED_TEMP dbspace in the
following cases:
• DQP_ENABLED is ON and there are read-write files in IQ_SHARED_TEMP
• DQP_ENABLED is OFF, TEMP_DATA_IN_SHARED_TEMP is ON, and there are
read-write files in IQ_SHARED_TEMP
• Example 11 – create a table tab1 that is enabled to use row-level versioning, and real-
time storage in the in-memory RLV store.
CREATE TABLE tab1 ( c1 INT, c2 CHAR(25) ) ENABLE RLV STORE
Usage
(back to top) on page 968
You can create a table for another user by specifying an owner name. If GLOBAL
TEMPORARY or LOCAL TEMPORARY is not specified, the table is referred to as a base
table. Otherwise, the table is a temporary table.
A created global temporary table exists in the database like a base table and remains in the
database until it is explicitly removed by a DROP TABLE statement. The rows in a temporary
table are visible only to the connection that inserted the rows. Multiple connections from the
same or different applications can use the same temporary table at the same time and each
connection sees only its own rows. A given connection inherits the schema of a global
temporary table as it exists when the connection first refers to the table. The rows of a
temporary table are deleted when the connection ends.
When you create a local temporary table, omit the owner specification. If you specify an owner
when creating a temporary table, for example, CREATE TABLE dbo.#temp(col1
int), a base table is incorrectly created.
An attempt to create a base table or a global temporary table will fail, if a local temporary table
of the same name exists on that connection, as the new table cannot be uniquely identified by
owner.table.
You can, however, create a local temporary table with the same name as an existing base table
or global temporary table. References to the table name access the local temporary table, as
local temporary tables are resolved first.
For example, consider this sequence:
CREATE TABLE t1 (c1 int);
INSERT t1 VALUES (9);
The result returned is 8. Any reference to t1 refers to the local temporary table t1 until the
local temporary table is dropped by the connection.
In a procedure, use the CREATE LOCAL TEMPORARY TABLE statement, instead of the
DECLARE LOCAL TEMPORARY TABLE statement, when you want to create a table that
persists after the procedure completes. Local temporary tables created using the CREATE
LOCAL TEMPORARY TABLE statement remain until they are either explicitly dropped, or
until the connection closes.
Local temporary tables created in IF statements using CREATE LOCAL TEMPORARY
TABLE also persist after the IF statement completes.
SAP Sybase IQ does not support the CREATE TABLE ENCRYPTED clause for table-level
encryption of SAP Sybase IQ tables. However, the CREATE TABLE ENCRYPTED clause is
supported for SQL Anywhere tables in an SAP Sybase IQ database.
Side Effects
Programming 983
Appendix: SQL Reference
• Automatic commit
Standards
(back to top) on page 968
• SQL–Vendor extension to ISO/ANSI SQL grammar.
These are vendor extensions:
• The { IN | ON } dbspace-name clause
• The ON COMMIT clause
• Some of the default values
• SAP Sybase Database product–Supported by Adaptive Server, with some differences.
• Temporary tables – you can create a temporary table by preceding the table name in a
CREATE TABLE statement with a pound sign (#). These temporary tables are SAP
Sybase IQ declared temporary tables, which are available only in the current
connection. For information about declared temporary tables, see DECLARE LOCAL
TEMPORARY TABLE Statement.
• Physical placement – physical placement of a table is carried out differently in SAP
Sybase IQ and in Adaptive Server. The ON segment-name clause supported by
Adaptive Server is supported in SAP Sybase IQ, but segment-name refers to an IQ
dbspace.
• Constraints – SAP Sybase IQ does not support named constraints or named defaults,
but does support user-defined data types that allow constraint and default definitions to
be encapsulated in the data type definition. It also supports explicit defaults and
CHECK conditions in the CREATE TABLE statement.
• NULL – (default) by default, columns in Adaptive Server default to NOT NULL,
whereas in SAP Sybase IQ the default setting is NULL, to allow NULL values. This
setting can be controlled using the ALLOW_NULLS_BY_DEFAULT option. See
ALLOW_NULLS_BY_DEFAULT Option [TSQL]. To make your data definition
statements transferable, explicitly specify NULL or NOT NULL.
Permissions
(back to top) on page 968
Programming 985
Appendix: SQL Reference
Syntax
DROP SERVER server-name
Examples
(back to top) on page 985
• Example 1 – this example drops the server IQ_prod:
DROP SERVER iq_prod
Usage
(back to top) on page 985
Before DROP SERVER succeeds, you must drop all the proxy tables that have been defined for
the remote server.
Side Effects
• Automatic commit
Standards
(back to top) on page 985
• SQL—ISO/ANSI SQL compliant.
• SAP Sybase Database product—Supported by Open Client/Open Server.
Permissions
(back to top) on page 985
Requites the SERVER OPERATOR system privilege.
Index
.NET
_close_extfn
data control 203
v4 API method 128
using theSAP Sybase IQ .NET Data Provider
_describe_extfn 25, 99
165
_enter_state_extfn 99
.NET API 211
_fetch_block_extfn
about 165
v4 API method 127
.NET Data Provider
_fetch_into_extfn
about 165
v4 API method 126
accessing data 170
_finish_extfn 98
adding a reference 167
_leave_state_extfn 99
connecting to a database 168
_open_extfn
connection pooling 169
v4 API method 126
dbdata.dll 195
_rewind_extfn
deleting data 170
v4 API method 128
deploying 194
_start_extfn 97
Entity Framework support 188
-d option
error handling 187
SQL preprocessor utility (iqsqlpp) 411
exception handling 187
-e option
executing stored procedures 185
SQL preprocessor utility (iqsqlpp) 411
features 166
-gn option
files required for deployment 194
threads 372
iAnywhere.Data.SQLAnywhere provider 166
-h option
inserting data 170
SQL preprocessor utility (iqsqlpp) 411
obtaining time values 184
-k option
POOLING option 169
SQL preprocessor utility (iqsqlpp) 411
referencing the provider classes in your source
-m option
code 167
SQL preprocessor utility (iqsqlpp) 411
registering 195
-n option
running the sample projects 167
SQL preprocessor utility (iqsqlpp) 411
supported languages 165
-o option
system requirements 194
SQL preprocessor utility (iqsqlpp) 411
tracing support 196
-q option
transaction processing 186
SQL preprocessor utility (iqsqlpp) 411
updating data 170
-r option
using the Simple code sample 200
SQL preprocessor utility (iqsqlpp) 411
using the Table Viewer code sample 201
-s option
versions supported 165
SQL preprocessor utility (iqsqlpp) 411
.NET database programming interfaces
-u option
tutorial 203
SQL preprocessor utility (iqsqlpp) 411
[database tools API] Autotune() enumeration 748
-w option
[database tools API] Checkpoint() enumeration
SQL preprocessor utility (iqsqlpp) 411
748
-x option
[database tools API] History() enumeration 748
SQL preprocessor utility (iqsqlpp) 411
[database tools API] Padding() enumeration 749
-z option
[database tools API] Unit() enumeration 749
SQL preprocessor utility (iqsqlpp) 411
Programming 987
Index
[database tools API] Unload() enumeration 749 a_backup_db structure [database tools API]
[database tools API] UserList() enumeration 749 confirmrtn MSG_CALLBACK 752
[database tools API] Validation() enumeration 750 a_backup_db structure [database tools API]
[database tools API] Verbosity() enumeration 750 connectparms const char * 752
[database tools API] Version() enumeration 750 a_backup_db structure [database tools API]
[SQL Anywhere .NET API] SABulkCopyOptions() description 751
enumeration 212 a_backup_db structure [database tools API] errorrtn
[SQL Anywhere .NET API] SAIsolationLevel() MSG_CALLBACK 753
enumeration 213 a_backup_db structure [database tools API]
[SQL Anywhere C API] a_sqlany_data_direction() hotlog_filename const char * 753
enumeration 518 a_backup_db structure [database tools API] msgrtn
[SQL Anywhere C API] a_sqlany_data_type() MSG_CALLBACK 753
enumeration 518 a_backup_db structure [database tools API]
[SQL Anywhere C API] a_sqlany_native_type() no_confirm a_bit_field 753
enumeration 519 a_backup_db structure [database tools API]
[SQL Anywhere C API] SACAPI_ERROR_SIZE output_dir const char * 753
variable 520 a_backup_db structure [database tools API]
[SQL Anywhere C API] page_blocksize a_sql_uint32 754
SQLANY_API_VERSION_1 variable a_backup_db structure [database tools API]
520 progress_messages a_bit_field 754
[SQL Anywhere C API] a_backup_db structure [database tools API] quiet
SQLANY_API_VERSION_2 variable a_bit_field 754
520 a_backup_db structure [database tools API]
@HttpMethod rename_local_log a_bit_field 754
accessing HTTP headers 641 a_backup_db structure [database tools API]
@HttpQueryString rename_log a_bit_field 754
accessing HTTP headers 641 a_backup_db structure [database tools API]
@HttpStatus server_backup a_bit_field 755
accessing HTTP headers 641 a_backup_db structure [database tools API]
@HttpURI statusrtn MSG_CALLBACK 755
accessing HTTP headers 641 a_backup_db structure [database tools API]
@HttpVersion truncate_log a_bit_field 755
accessing HTTP headers 641 a_backup_db structure [database tools API] version
unsigned short 755
A a_backup_db structure [database tools API]
wait_after_end a_bit_field 755
a_backup_db structure [database tools API]
a_backup_db structure [database tools API]
auto_tune_writers char 751
wait_before_start a_bit_field 756
a_backup_db structure [database tools API]
a_change_log structure [database tools API]
backup_comment const char * 751
change_logname a_bit_field 756
a_backup_db structure [database tools API]
a_change_log structure [database tools API]
backup_database a_bit_field 751
change_mirrorname a_bit_field 756
a_backup_db structure [database tools API]
a_change_log structure [database tools API]
backup_history char 751
dbname const char * 756
a_backup_db structure [database tools API]
a_change_log structure [database tools API]
backup_interrupted char 752
description 756
a_backup_db structure [database tools API]
a_change_log structure [database tools API]
backup_logfile a_bit_field 752
encryption_key char * 757
a_backup_db structure [database tools API]
chkpt_log_type char 752
a_change_log structure [database tools API] a_create_db structure [database tools API] dbname
errorrtn MSG_CALLBACK 757 const char * 761
a_change_log structure [database tools API] a_create_db structure [database tools API]
generation_number unsigned short 757 default_collation const char * 762
a_change_log structure [database tools API] a_create_db structure [database tools API]
ignore_dbsync_trunc a_bit_field 757 description 759
a_change_log structure [database tools API] a_create_db structure [database tools API] encoding
ignore_ltm_trunc a_bit_field 757 const char * 762
a_change_log structure [database tools API] a_create_db structure [database tools API] encrypt
ignore_remote_trunc a_bit_field 757 a_bit_field 762
a_change_log structure [database tools API] a_create_db structure [database tools API]
logname const char * 758 encrypted_tables a_bit_field 762
a_change_log structure [database tools API] a_create_db structure [database tools API]
mirrorname const char * 758 encryption_algorithm const char * 762
a_change_log structure [database tools API] msgrtn a_create_db structure [database tools API]
MSG_CALLBACK 758 encryption_key const char * 763
a_change_log structure [database tools API] a_create_db structure [database tools API] errorrtn
query_only a_bit_field 758 MSG_CALLBACK 763
a_change_log structure [database tools API] quiet a_create_db structure [database tools API]
a_bit_field 758 iq_params void * 763
a_change_log structure [database tools API] a_create_db structure [database tools API] jconnect
set_generation_number a_bit_field 758 a_bit_field 763
a_change_log structure [database tools API] version a_create_db structure [database tools API] logname
unsigned short 759 const char * 763
a_change_log structure [database tools API] a_create_db structure [database tools API]
zap_current_offset char * 759 mirrorname const char * 763
a_change_log structure [database tools API] a_create_db structure [database tools API] msgrtn
zap_starting_offset char * 759 MSG_CALLBACK 764
a_create_db structure [database tools API] a_create_db structure [database tools API]
accent_sensitivity char 759 nchar_collation const char * 764
a_create_db structure [database tools API] a_create_db structure [database tools API]
avoid_view_collisions a_bit_field 760 page_size unsigned short 764
a_create_db structure [database tools API] a_create_db structure [database tools API]
blank_pad a_bit_field 760 respect_case a_bit_field 764
a_create_db structure [database tools API] a_create_db structure [database tools API] startline
case_sensitivity_use_default a_bit_field const char * 764
760 a_create_db structure [database tools API]
a_create_db structure [database tools API] sys_proc_definer a_bit_field 765
checksum a_bit_field 760 a_create_db structure [database tools API] verbose
a_create_db structure [database tools API] char 765
data_store_type const char * 761 a_create_db structure [database tools API] version
a_create_db structure [database tools API] db_size unsigned short 765
unsigned int 761 a_db_info structure [database tools API]
a_create_db structure [database tools API] bit_map_pages a_sql_uint32 765
db_size_unit int 761 a_db_info structure [database tools API]
a_create_db structure [database tools API] dba_pwd charcollationspecbuffer char * 765
char * 761 a_db_info structure [database tools API]
a_create_db structure [database tools API] dba_uid charcollationspecbufsize unsigned short
char * 761 766
Programming 989
Index
a_db_info structure [database tools API] a_db_info structure [database tools API] statusrtn
charencodingbuffer char * 766 MSG_CALLBACK 769
a_db_info structure [database tools API] a_db_info structure [database tools API] sysinfo
charencodingbufsize unsigned short 766 a_sysinfo 769
a_db_info structure [database tools API] checksum a_db_info structure [database tools API] totals
a_bit_field 766 a_table_info * 770
a_db_info structure [database tools API] a_db_info structure [database tools API] version
connectparms const char * 766 unsigned short 770
a_db_info structure [database tools API] dbbufsize a_db_version_info structure [database tools API]
unsigned short 767 created_version char 770
a_db_info structure [database tools API] a_db_version_info structure [database tools API]
dbnamebuffer char * 767 description 770
a_db_info structure [database tools API] description a_db_version_info structure [database tools API]
765 errorrtn MSG_CALLBACK 770
a_db_info structure [database tools API] a_db_version_info structure [database tools API]
encrypted_tables a_bit_field 767 filename const char * 770
a_db_info structure [database tools API] errorrtn a_db_version_info structure [database tools API]
MSG_CALLBACK 767 msgrtn MSG_CALLBACK 771
a_db_info structure [database tools API] file_size a_db_version_info structure [database tools API]
a_sql_uint32 767 version unsigned short 771
a_db_info structure [database tools API] free_pages a_dblic_info structure [database tools API]
a_sql_uint32 767 compname char * 771
a_db_info structure [database tools API] logbufsize a_dblic_info structure [database tools API]
unsigned short 767 conncount a_sql_int32 771
a_db_info structure [database tools API] a_dblic_info structure [database tools API]
lognamebuffer char * 768 description 771
a_db_info structure [database tools API] a_dblic_info structure [database tools API] errorrtn
mirrorbufsize unsigned short 768 MSG_CALLBACK 771
a_db_info structure [database tools API] a_dblic_info structure [database tools API]
mirrornamebuffer char * 768 exename char * 772
a_db_info structure [database tools API] msgrtn a_dblic_info structure [database tools API]
MSG_CALLBACK 768 installkey char * 772
a_db_info structure [database tools API] a_dblic_info structure [database tools API] msgrtn
ncharcollationspecbuffer char * 768 MSG_CALLBACK 772
a_db_info structure [database tools API] a_dblic_info structure [database tools API]
ncharcollationspecbufsize unsigned short nodecount a_sql_int32 772
768 a_dblic_info structure [database tools API]
a_db_info structure [database tools API] query_only a_bit_field 772
ncharencodingbuffer char * 768 a_dblic_info structure [database tools API] quiet
a_db_info structure [database tools API] a_bit_field 772
ncharencodingbufsize unsigned short a_dblic_info structure [database tools API] type
769 a_license_type 773
a_db_info structure [database tools API] a_dblic_info structure [database tools API]
other_pages a_sql_uint32 769 username char * 773
a_db_info structure [database tools API] a_dblic_info structure [database tools API] version
page_usage a_bit_field 769 unsigned short 773
a_db_info structure [database tools API] quiet a_dbtools_info structure [database tools API]
a_bit_field 769 description 773
a_dbtools_info structure [database tools API] a_remote_sql structure [database tools API]
errorrtn MSG_CALLBACK 773 description 775
a_log_file_info structure [database tools API] a_remote_sql structure [database tools API]
dbname const char * 774 encryption_key char * 778
a_log_file_info structure [database tools API] a_remote_sql structure [database tools API] errorrtn
description 773 MSG_CALLBACK 778
a_log_file_info structure [database tools API] a_remote_sql structure [database tools API]
encryption_key const char * 774 frequency a_sql_uint32 779
a_log_file_info structure [database tools API] a_remote_sql structure [database tools API]
errorrtn MSG_CALLBACK 774 full_q_scan a_bit_field 779
a_log_file_info structure [database tools API] a_remote_sql structure [database tools API]
logname char * 774 include_scan_range char * 779
a_log_file_info structure [database tools API] a_remote_sql structure [database tools API]
logname_size size_t 774 latest_backup a_bit_field 779
a_log_file_info structure [database tools API] a_remote_sql structure [database tools API]
mirrorname char * 774 link_debug a_bit_field 779
a_log_file_info structure [database tools API] a_remote_sql structure [database tools API] locale
mirrorname_size size_t 774 char * 779
a_log_file_info structure [database tools API] a_remote_sql structure [database tools API]
reserved void * 775 log_file_name const char * 780
a_log_file_info structure [database tools API] a_remote_sql structure [database tools API]
version unsigned short 775 log_size a_sql_uint32 780
a_name structure [database tools API] description a_remote_sql structure [database tools API] logrtn
775 MSG_CALLBACK 780
a_name structure [database tools API] name char a_remote_sql structure [database tools API]
775 max_length a_sql_uint32 780
a_name structure [database tools API] next struct a_remote_sql structure [database tools API]
a_name * 775 memory a_sql_uint32 781
a_remote_sql structure [database tools API] apply a_remote_sql structure [database tools API]
a_bit_field 776 mirror_logs char * 781
a_remote_sql structure [database tools API] argv a_remote_sql structure [database tools API] more
char ** 776 a_bit_field 781
a_remote_sql structure [database tools API] batch a_remote_sql structure [database tools API]
a_bit_field 777 msgqueuertn
a_remote_sql structure [database tools API] MSG_QUEUE_CALLBACK 781
confirmrtn MSG_CALLBACK 777 a_remote_sql structure [database tools API] msgrtn
a_remote_sql structure [database tools API] MSG_CALLBACK 781
connectparms char * 777 a_remote_sql structure [database tools API]
a_remote_sql structure [database tools API] debug no_user_interaction a_bit_field 782
a_bit_field 777 a_remote_sql structure [database tools API]
a_remote_sql structure [database tools API] operations a_sql_uint32 782
debug_dump_size a_sql_uint32 778 a_remote_sql structure [database tools API]
a_remote_sql structure [database tools API] patience_retry a_sql_uint32 782
debug_page_offsets a_bit_field 778 a_remote_sql structure [database tools API]
a_remote_sql structure [database tools API] progress_index_rtn
default_window_title char * 778 SET_PROGRESS_CALLBACK 782
a_remote_sql structure [database tools API] deleted a_remote_sql structure [database tools API]
a_bit_field 778 progress_msg_rtn MSG_CALLBACK
783
Programming 991
Index
Programming 993
Index
a_sync_db structure [database tools API] a_sync_db structure [database tools API]
ignore_hovering a_bit_field 795 output_to_mobile_link a_bit_field 799
a_sync_db structure [database tools API] a_sync_db structure [database tools API]
ignore_scheduling a_bit_field 795 persist_connection a_bit_field 799
a_sync_db structure [database tools API] a_sync_db structure [database tools API] ping
include_scan_range const char * 795 a_bit_field 800
a_sync_db structure [database tools API] init_cache a_sync_db structure [database tools API]
a_sql_uint32 795 preload_dlls char * 800
a_sync_db structure [database tools API] a_sync_db structure [database tools API]
init_cache_suffix char 795 progress_index_rtn
a_sync_db structure [database tools API] SET_PROGRESS_CALLBACK 800
kill_other_connections a_bit_field 796 a_sync_db structure [database tools API]
a_sync_db structure [database tools API] progress_msg_rtn MSG_CALLBACK
last_upload_def a_syncpub * 796 800
a_sync_db structure [database tools API] a_sync_db structure [database tools API]
lite_blob_handling a_bit_field 796 prompt_again a_bit_field 800
a_sync_db structure [database tools API] a_sync_db structure [database tools API]
log_file_name const char * 796 prompt_for_encrypt_key a_bit_field 800
a_sync_db structure [database tools API] log_size a_sync_db structure [database tools API]
a_sql_uint32 796 protocol_add_cli_bit_to_cli_both
a_sync_db structure [database tools API] logrtn a_bit_field 801
MSG_CALLBACK 797 a_sync_db structure [database tools API]
a_sync_db structure [database tools API] protocol_add_cli_bit_to_cli_max
max_cache a_sql_uint32 797 a_bit_field 801
a_sync_db structure [database tools API] a_sync_db structure [database tools API]
max_cache_suffix char 797 protocol_add_serv_bit_to_cli_both
a_sync_db structure [database tools API] a_bit_field 801
min_cache a_sql_uint32 797 a_sync_db structure [database tools API]
a_sync_db structure [database tools API] protocol_add_serv_bit_to_cli_max
min_cache_suffix char 797 a_bit_field 801
a_sync_db structure [database tools API] a_sync_db structure [database tools API]
mlpassword char * 797 protocol_add_serv_bit_to_serv_both
a_sync_db structure [database tools API] a_bit_field 801
msgqueuertn a_sync_db structure [database tools API]
MSG_QUEUE_CALLBACK 798 protocol_add_serv_bit_to_serv_max
a_sync_db structure [database tools API] msgrtn a_bit_field 801
MSG_CALLBACK 798 a_sync_db structure [database tools API] raw_file
a_sync_db structure [database tools API] const char * 801
new_mlpassword char * 798 a_sync_db structure [database tools API]
a_sync_db structure [database tools API] rename_log a_bit_field 802
no_offline_logscan a_sql_uint32 798 a_sync_db structure [database tools API] reserved
a_sync_db structure [database tools API] a_bit_field 802
no_schema_cache a_bit_field 799 a_sync_db structure [database tools API]
a_sync_db structure [database tools API] retry_remote_ahead a_bit_field 802
no_stream_compress a_bit_field 799 a_sync_db structure [database tools API]
a_sync_db structure [database tools API] offline_dir retry_remote_behind a_bit_field 802
const char * 799 a_sync_db structure [database tools API]
a_sync_db structure [database tools API] server_mode a_bit_field 802
output_to_file a_bit_field 799
a_sync_db structure [database tools API] a_sync_db structure [database tools API]
server_port a_sql_uint32 803 verbose_msgid a_bit_field 807
a_sync_db structure [database tools API] a_sync_db structure [database tools API]
set_window_title_rtn verbose_option_info a_bit_field 807
SET_WINDOW_TITLE_CALLBACK a_sync_db structure [database tools API]
803 verbose_protocol a_bit_field 807
a_sync_db structure [database tools API] status_rtn a_sync_db structure [database tools API]
STATUS_CALLBACK 803 verbose_row_cnts a_bit_field 807
a_sync_db structure [database tools API] a_sync_db structure [database tools API]
strictly_free_memory a_bit_field 803 verbose_row_data a_bit_field 807
a_sync_db structure [database tools API] a_sync_db structure [database tools API]
strictly_ignore_trigger_ops a_bit_field verbose_server a_bit_field 808
803 a_sync_db structure [database tools API]
a_sync_db structure [database tools API] sync_opt verbose_upload a_bit_field 808
char * 803 a_sync_db structure [database tools API]
a_sync_db structure [database tools API] verbose_upload_data a_bit_field 808
sync_params char * 804 a_sync_db structure [database tools API] version
a_sync_db structure [database tools API] unsigned short 808
sync_profile char * 804 a_sync_db structure [database tools API]
a_sync_db structure [database tools API] warningrtn MSG_CALLBACK 808
trans_upload a_bit_field 804 a_syncpub structure [database tools API]
a_sync_db structure [database tools API] description 808
upld_fail_len a_sql_uint32 804 a_syncpub structure [database tools API] ext_opt
a_sync_db structure [database tools API] char * 809
upload_defs a_syncpub * 804 a_syncpub structure [database tools API] next struct
a_sync_db structure [database tools API] a_syncpub * 809
upload_only a_bit_field 805 a_syncpub structure [database tools API] pub_name
a_sync_db structure [database tools API] usage_rtn char * 809
USAGE_CALLBACK 805 a_syncpub structure [database tools API]
a_sync_db structure [database tools API] subscription char * 809
use_fixed_cache a_bit_field 805 a_sysinfo structure [database tools API]
a_sync_db structure [database tools API] blank_padding a_bit_field 810
use_hex_offsets a_bit_field 805 a_sysinfo structure [database tools API]
a_sync_db structure [database tools API] case_sensitivity a_bit_field 810
use_relative_offsets a_bit_field 805 a_sysinfo structure [database tools API]
a_sync_db structure [database tools API] default_collation char 810
used_dialog_allocation a_bit_field 805 a_sysinfo structure [database tools API] description
a_sync_db structure [database tools API] 809
user_name char * 806 a_sysinfo structure [database tools API] encryption
a_sync_db structure [database tools API] verbose a_bit_field 810
a_bit_field 806 a_sysinfo structure [database tools API] page_size
a_sync_db structure [database tools API] unsigned short 810
verbose_download a_bit_field 806 a_sysinfo structure [database tools API] valid_data
a_sync_db structure [database tools API] a_bit_field 810
verbose_download_data a_bit_field 806 a_table_info structure [database tools API]
a_sync_db structure [database tools API] description 810
verbose_hook a_bit_field 806 a_table_info structure [database tools API]
a_sync_db structure [database tools API] index_pages a_sql_uint32 811
verbose_minimum a_bit_field 806
Programming 995
Index
a_table_info structure [database tools API] a_translate_log structure [database tools API]
index_used a_sql_uint32 811 force_recovery a_bit_field 815
a_table_info structure [database tools API] a_translate_log structure [database tools API]
index_used_pct a_sql_uint32 811 generate_reciprocals a_bit_field 815
a_table_info structure [database tools API] next a_translate_log structure [database tools API]
struct a_table_info * 811 include_audit a_bit_field 815
a_table_info structure [database tools API] table_id a_translate_log structure [database tools API]
a_sql_uint32 811 include_destination_sets const char *
a_table_info structure [database tools API] 815
table_name char * 811 a_translate_log structure [database tools API]
a_table_info structure [database tools API] include_publications const char * 815
table_pages a_sql_uint32 811 a_translate_log structure [database tools API]
a_table_info structure [database tools API] include_scan_range const char * 815
table_used a_sql_uint32 812 a_translate_log structure [database tools API]
a_table_info structure [database tools API] include_source_sets const char * 815
table_used_pct a_sql_uint32 812 a_translate_log structure [database tools API]
a_translate_log structure [database tools API] include_subsets a_bit_field 816
ansi_sql a_bit_field 812 a_translate_log structure [database tools API]
a_translate_log structure [database tools API] include_tables const char * 816
chronological_order a_bit_field 812 a_translate_log structure [database tools API]
a_translate_log structure [database tools API] include_trigger_trans a_bit_field 816
comment_trigger_trans a_bit_field 812 a_translate_log structure [database tools API]
a_translate_log structure [database tools API] leave_output_on_error a_bit_field 816
confirmrtn MSG_CALLBACK 813 a_translate_log structure [database tools API]
a_translate_log structure [database tools API] logname const char * 816
connectparms const char * 813 a_translate_log structure [database tools API] logrtn
a_translate_log structure [database tools API] debug MSG_CALLBACK 816
a_bit_field 813 a_translate_log structure [database tools API]
a_translate_log structure [database tools API] logs_dir const char * 817
debug_dump_char a_bit_field 813 a_translate_log structure [database tools API]
a_translate_log structure [database tools API] match_mode a_bit_field 817
debug_dump_hex a_bit_field 813 a_translate_log structure [database tools API]
a_translate_log structure [database tools API] match_pos const char * 817
debug_dump_size a_sql_uint32 814 a_translate_log structure [database tools API]
a_translate_log structure [database tools API] msgrtn MSG_CALLBACK 817
debug_page_offsets a_bit_field 814 a_translate_log structure [database tools API]
a_translate_log structure [database tools API] omit_comments a_bit_field 817
debug_sql_remote a_bit_field 814 a_translate_log structure [database tools API]
a_translate_log structure [database tools API] queueparms const char * 817
description 812 a_translate_log structure [database tools API] quiet
a_translate_log structure [database tools API] a_bit_field 818
encryption_key const char * 814 a_translate_log structure [database tools API]
a_translate_log structure [database tools API] recovery_bytes a_sql_uint32 818
errorrtn MSG_CALLBACK 814 a_translate_log structure [database tools API]
a_translate_log structure [database tools API] recovery_ops a_sql_uint32 818
extra_audit a_bit_field 814 a_translate_log structure [database tools API]
a_translate_log structure [database tools API] remove_rollback a_bit_field 818
force_chaining a_bit_field 814 a_translate_log structure [database tools API]
replace a_bit_field 818
Programming 997
Index
a_v4_extfn_table_func ADO
structure 124 about 320
table functions 124 Command object 322
a_validate_db structure [database tools API] commands 322
connectparms const char * 822 Connection object 321
a_validate_db structure [database tools API] connections 321
description 822 cursor types 142
a_validate_db structure [database tools API] cursors 158
errorrtn MSG_CALLBACK 823 introduction to programming 319
a_validate_db structure [database tools API] index queries 323
a_bit_field 823 Recordset object 323
a_validate_db structure [database tools API] msgrtn Recordset object and cursor types 324
MSG_CALLBACK 823 transactions 326
a_validate_db structure [database tools API] quiet updates 325
a_bit_field 823 updating data through a cursor 325
a_validate_db structure [database tools API] using SQL statements in applications 131
statusrtn MSG_CALLBACK 823 ADO.NET
a_validate_db structure [database tools API] tables about 165
p_name 823 autocommit mode 161
a_validate_db structure [database tools API] type controlling autocommit behavior 161
char 824 cursor support 158
a_validate_db structure [database tools API] version prepared statements 133
unsigned short 824 using SQL statements in applications 131
Abort propertySARowsCopiedEventArgs class ADO.NET API
[SQL Anywhere .NET API] 307 about 165
about 423–426, 435, 436, 481, 482 aggregate functions 859
accent_sensitivity chara_create_db structure statistical 881
[database tools API] 759 STDDEV_POP 882
Accept STDDEV_SAMP 882
accessing HTTP headers 641 VAR_POP 882
Accept-Charset VAR_SAMP 882
accessing HTTP headers 641 All propertySACommLinksOptionsBuilder class
Accept-Encoding [SQL Anywhere .NET API] 224
accessing HTTP headers 641 alloc
Accept-Language v4 API method 109
accessing HTTP headers 641 alloc_sqlda function
AcceptCharset option about 467
example 652 alloc_sqlda_noind function
ActiveX Data Objects about 468
about 320 ALLOW_NULLS_BY_DEFAULT option
Adaptive Server server 946 Open Client 6
Adaptive Server servers 944 allow_outside_connect a_bit_fielda_sync_db
addBatch structure [database tools API] 787
PreparedStatement class 398 allow_schema_change a_bit_fielda_sync_db
Statement class 393 structure [database tools API] 787
addShutdownHook ALTER SERVER statement
Java VM shutdown hooks 374 syntax 961
administration tools altering
dbtools 731 web services 631
an_erase_db structure [database tools API] an_unload_db structure [database tools API]
confirmrtn MSG_CALLBACK 824 exclude_procedures a_bit_field 829
an_erase_db structure [database tools API] dbname an_unload_db structure [database tools API]
const char * 824 exclude_tables a_bit_field 829
an_erase_db structure [database tools API] an_unload_db structure [database tools API]
description 824 exclude_triggers a_bit_field 829
an_erase_db structure [database tools API] an_unload_db structure [database tools API]
encryption_key const char * 824 exclude_views a_bit_field 829
an_erase_db structure [database tools API] erase an_unload_db structure [database tools API] extract
a_bit_field 825 a_bit_field 830
an_erase_db structure [database tools API] errorrtn an_unload_db structure [database tools API]
MSG_CALLBACK 825 genscript a_bit_field 830
an_erase_db structure [database tools API] msgrtn an_unload_db structure [database tools API]
MSG_CALLBACK 825 include_where_subscribe a_bit_field 830
an_erase_db structure [database tools API] quiet an_unload_db structure [database tools API]
a_bit_field 825 isolation_level unsigned short 830
an_erase_db structure [database tools API] version an_unload_db structure [database tools API]
unsigned short 825 isolation_set a_bit_field 830
an_unload_db structure [database tools API] an_unload_db structure [database tools API] locale
compress_output a_bit_field 826 const char * 831
an_unload_db structure [database tools API] an_unload_db structure [database tools API]
confirmrtn MSG_CALLBACK 826 make_auxiliary a_bit_field 831
an_unload_db structure [database tools API] an_unload_db structure [database tools API]
connectparms const char * 826 ms_filename const char * 831
an_unload_db structure [database tools API] debug an_unload_db structure [database tools API]
a_bit_field 827 ms_reserve int 831
an_unload_db structure [database tools API] an_unload_db structure [database tools API]
description 826 ms_size int 831
an_unload_db structure [database tools API] an_unload_db structure [database tools API] msgrtn
display_create a_bit_field 827 MSG_CALLBACK 831
an_unload_db structure [database tools API] an_unload_db structure [database tools API]
display_create_dbinit a_bit_field 827 no_confirm a_bit_field 832
an_unload_db structure [database tools API] an_unload_db structure [database tools API]
encrypted_tables a_bit_field 827 no_reload_status a_bit_field 832
an_unload_db structure [database tools API] an_unload_db structure [database tools API]
encryption_algorithm const char * 827 notemp_size long 832
an_unload_db structure [database tools API] an_unload_db structure [database tools API]
encryption_key const char * 828 preserve_identity_values a_bit_field 832
an_unload_db structure [database tools API] an_unload_db structure [database tools API]
errorrtn MSG_CALLBACK 828 preserve_ids a_bit_field 832
an_unload_db structure [database tools API] an_unload_db structure [database tools API]
escape_char char 828 profiling_uses_single_dbspace
an_unload_db structure [database tools API] a_bit_field 833
escape_char_present a_bit_field 828 an_unload_db structure [database tools API]
an_unload_db structure [database tools API] recompute a_bit_field 833
exclude_foreign_keys a_bit_field 828 an_unload_db structure [database tools API]
an_unload_db structure [database tools API] refresh_mat_view a_bit_field 833
exclude_hooks a_bit_field 829 an_unload_db structure [database tools API]
reload_connectparms char * 833
Programming 999
Index
an_unload_db structure [database tools API] an_unload_db structure [database tools API]
reload_db_filename char * 833 unordered a_bit_field 838
an_unload_db structure [database tools API] an_unload_db structure [database tools API]
reload_db_logname char * 834 use_internal_reload a_bit_field 838
an_unload_db structure [database tools API] an_unload_db structure [database tools API]
reload_filename const char * 834 use_internal_unload a_bit_field 838
an_unload_db structure [database tools API] an_unload_db structure [database tools API]
reload_page_size unsigned short 834 verbose char 838
an_unload_db structure [database tools API] an_unload_db structure [database tools API]
remote_dir const char * 834 version unsigned short 839
an_unload_db structure [database tools API] an_upgrade_db structure [database tools API]
remove_encrypted_tables a_bit_field connectparms const char * 839
834 an_upgrade_db structure [database tools API]
an_unload_db structure [database tools API] description 839
replace_db a_bit_field 835 an_upgrade_db structure [database tools API]
an_unload_db structure [database tools API] errorrtn MSG_CALLBACK 839
runscript a_bit_field 835 an_upgrade_db structure [database tools API]
an_unload_db structure [database tools API] jconnect a_bit_field 839
schema_reload a_bit_field 835 an_upgrade_db structure [database tools API]
an_unload_db structure [database tools API] msgrtn MSG_CALLBACK 840
site_name const char * 835 an_upgrade_db structure [database tools API] quiet
an_unload_db structure [database tools API] a_bit_field 840
start_subscriptions a_bit_field 835 an_upgrade_db structure [database tools API]
an_unload_db structure [database tools API] restart a_bit_field 840
startline const char * 836 an_upgrade_db structure [database tools API]
an_unload_db structure [database tools API] statusrtn MSG_CALLBACK 840
startline_name a_bit_field 836 an_upgrade_db structure [database tools API]
an_unload_db structure [database tools API] sys_proc_definer unsigned short 840
startline_old const char * 836 an_upgrade_db structure [database tools API]
an_unload_db structure [database tools API] version unsigned short 841
statusrtn MSG_CALLBACK 836 analytic functions
an_unload_db structure [database tools API] DENSE_RANK 873
subscriber_username const char * 836 PERCENT_RANK 875
an_unload_db structure [database tools API] PERCENTILE_CONT 888
suppress_statistics a_bit_field 836 PERCENTILE_DISC 890
an_unload_db structure [database tools API] sysinfo RANK 871
a_sysinfo 837 analytical functions 843
an_unload_db structure [database tools API] ansi_sql a_bit_fielda_translate_log structure
table_list p_name 837 [database tools API] 812
an_unload_db structure [database tools API] APIs
table_list_provided a_bit_field 837 ADO API 319
an_unload_db structure [database tools API] ADO.NET 165
temp_dir const char * 837 JDBC API 377
an_unload_db structure [database tools API] OLE DB API 319
template_name const char * 837 Perl DBD::SQLAnywhere API 535
an_unload_db structure [database tools API] PHP 566
unload_interrupted char 837 Python Database API 545
an_unload_db structure [database tools API] Ruby APIs 591
unload_type char 838 Sybase Open Client API 617
Programming 1001
Index
Programming 1003
Index
commenting Connection
web services 634 accessing HTTP headers 641
commit method Connection ADO object
Python 549 ADO 321
COMMIT statement ADO programming 326
cursors 163 connection defaults 390
JDBC 390 connection parameters
remote data access 954 OLE DB 327
CommitTrans ADO method connection pooling
ADO programming 326 .NET Data Provider 169
updating data 326 OLE DB 329
CommLinks propertySAConnectionStringBuilder web services 637
class [SQL Anywhere .NET API] 248 connection properties
compile and link process web services 654
about 410 Connection propertySACommand class [SQL
compilers Anywhere .NET API] 236
used with sqlpp 415 Connection propertySATransaction class [SQL
compname char *a_dblic_info structure [database Anywhere .NET API] 316
tools API] 771 connection state
Component Integration Services 945 .NET Data Provider 170
Compress propertySAConnectionStringBuilder CONNECTION_PROPERTY function
class [SQL Anywhere .NET API] 248 example 651
compress_output a_bit_fieldan_unload_db ConnectionLifetime
structure [database tools API] 826 propertySAConnectionStringBuilder
CompressionThreshold class [SQL Anywhere .NET API] 248
propertySAConnectionStringBuilder ConnectionName
class [SQL Anywhere .NET API] 248 propertySAConnectionStringBuilder
computing deltas between adjacent rows 869 class [SQL Anywhere .NET API] 249
confirmrtn MSG_CALLBACKa_backup_db ConnectionPool
structure [database tools API] 752 propertySAConnectionStringBuilder
confirmrtn MSG_CALLBACKa_remote_sql class [SQL Anywhere .NET API] 249
structure [database tools API] 777 ConnectionReset
confirmrtn MSG_CALLBACKa_sync_db structure propertySAConnectionStringBuilder
[database tools API] 789 class [SQL Anywhere .NET API] 249
confirmrtn MSG_CALLBACKa_translate_log connections 390
structure [database tools API] 813 ADO Connection object 321
confirmrtn MSG_CALLBACKan_erase_db connecting to a database using the .NET Data
structure [database tools API] 824 Provider 168
confirmrtn MSG_CALLBACKan_unload_db functions 486
structure [database tools API] 826 jConnect 384
conncount a_sql_int32a_dblic_info structure jConnect URL 383
[database tools API] 771 JDBC 380
connect identifier JDBC client applications 384
resolving 943 JDBC example 384
connect method JDBC in the server 388
Python 548 JDBC server-side example 388
connecting licensing web applications 646
OLE DB 320 ODBC functions 346
ODBC programming 347
Programming 1005
Index
Programming 1007
Index
Programming 1009
Index
direction DllMain
a_sqlany_data_directiona_sqlany_bind_ calling db_fini 475
param structure [SQL Anywhere C API] DLLs
528 multiple SQLCAs 439
direction dnld_fail_len a_sql_uint32a_sync_db structure
a_sqlany_data_directiona_sqlany_bind_ [database tools API] 791
param_info structure [SQL Anywhere C dnld_file_extra const char *a_sync_db structure
API] 529 [database tools API] 792
Direction propertySAParameter class [SQL dnld_gen_num a_bit_fielda_sync_db structure
Anywhere .NET API] 291 [database tools API] 792
DisableMultiRowFetch dnld_read_size a_sql_uint32a_sync_db structure
propertySAConnectionStringBuilder [database tools API] 792
class [SQL Anywhere .NET API] 251 DoBroadcast propertySATcpOptionsBuilder class
DISH services [SQL Anywhere .NET API] 312
.NET tutorial 709 download_only a_bit_fielda_sync_db structure
about 629 [database tools API] 792
commenting 634 DREnumerator class [SQL Anywhere .NET API]
creating 633 Current property 271
dropping 634 DREnumerator class [SQL Anywhere .NET API]
homogeneous 634 description 270
JAX-WS tutorial 715 driver load error 943
SAP Sybase IQ web client tutorial 701 drivers
display_create a_bit_fieldan_unload_db structure jConnect JDBC driver 378
[database tools API] 827 linking the SAP Sybase IQ ODBC driver on
display_create_dbinit a_bit_fieldan_unload_db Windows 340
structure [database tools API] 827 SQL Anywhere JDBC driver 378
Distributed Transaction Coordinator DROP SERVER statement
three-tier computing 727 syntax 985
distributed transaction processing dropping
using the SAP Sybase IQ .NET Data Provider web services 634
186 DT_BIGINT embedded SQL data type 423
distributed transactions DT_BINARY embedded SQL data type 425
about 725 DT_BIT embedded SQL data type 423
architecture 728 DT_DATE embedded SQL data type 424
enlistment 727 DT_DECIMAL embedded SQL data type 424
recovery 729 DT_DOUBLE embedded SQL data type 423
restrictions 728 DT_FIXCHAR embedded SQL data type 424
three-tier computing 726 DT_FLOAT embedded SQL data type 423
distribution functions 843, 860, 886 DT_HAS_USERTYPE_INFO 445
dl_insert_width a_sql_uint32a_sync_db structure DT_INT embedded SQL data type 423
[database tools API] 791 DT_LONGBINARY embedded SQL data type
dl_use_put a_bit_fielda_sync_db structure 425
[database tools API] 791 DT_LONGNVARCHAR embedded SQL data type
dlg_info_msg a_sql_uint32a_sync_db structure 425
[database tools API] 791 DT_LONGVARCHAR embedded SQL data type
DLL entry points 424
about 467 DT_NFIXCHAR embedded SQL data type 424
dll_handle void *SQLAnywhereInterface structure DT_NSTRING embedded SQL data type 424
[SQL Anywhere C API] 521 DT_NVARCHAR embedded SQL data type 424
Programming 1011
Index
Programming 1013
Index
EXTFNAPIV4_DESCRIBE_COL_VALUES_SU EXTFNAPIV4_DESCRIBE_PARM_TABLE_RE
BSET_OF_INPUT QUEST_REWIND
get 40 get 70
set 54 set 83
EXTFNAPIV4_DESCRIBE_COL_WIDTH EXTFNAPIV4_DESCRIBE_PARM_TABLE_UN
set 28, 43 USED_COLUMNS
EXTFNAPIV4_DESCRIBE_PARM_CAN_BE_N get 71
ULL set 85
get 60, 61 EXTFNAPIV4_DESCRIBE_PARM_TYPE
set 77 get 57
EXTFNAPIV4_DESCRIBE_PARM_CONSTANT set 74
_VALUE EXTFNAPIV4_DESCRIBE_PARM_WIDTH
get 65 get 57
set 78 set 75
EXTFNAPIV4_DESCRIBE_PARM_DISTINCT_ EXTFNAPIV4_DESCRIBE_UDF_NUM_PARM
VALUES S
get 62 get 87
set 77 set 89
EXTFNAPIV4_DESCRIBE_PARM_IS_CONSTA extra_audit a_bit_fielda_translate_log structure
NT [database tools API] 814
get 64 extract a_bit_fieldan_unload_db structure [database
set 78 tools API] 830
EXTFNAPIV4_DESCRIBE_PARM_NAME
get 56
set 74 F
EXTFNAPIV4_DESCRIBE_PARM_SCALE fat cursors
get 59 about 139
set 76 FETCH FOR UPDATE
EXTFNAPIV4_DESCRIBE_PARM_TABLE_HA embedded SQL 155
S_REWIND ODBC 155
get 70 fetch operation
set 84 cursors 138
EXTFNAPIV4_DESCRIBE_PARM_TABLE_NU multiple rows 139
M_COLUMNS scrollable cursors 139
get 66 FETCH statement
set 79 dynamic queries 442
EXTFNAPIV4_DESCRIBE_PARM_TABLE_NU multi-row 456
M_ROWS using 452
get 66 using cursors in embedded SQL 453
set 80 wide 456
EXTFNAPIV4_DESCRIBE_PARM_TABLE_OR fetch_block
DERBY v4 API method 121
get 67 fetch_into
set 81 v4 API method 119
EXTFNAPIV4_DESCRIBE_PARM_TABLE_PA fetchall method
RTITIONBY Python 548
get 68 fetches
set 82 array fetches 456
wide fetches 456
Programming 1015
Index
Programming 1017
Index
Programming 1019
Index
Programming 1021
Index
Programming 1023
Index
Programming 1025
Index
Programming 1027
Index
Programming 1029
Index
raw_file const char *a_sync_db structure [database remote data access 5, 961
tools API] 801 internal operations 955
READ_CLIENT_FILE function remote servers 940
ESQL client API callback function 480 troubleshooting 957
read-only cursors remote procedure calls
about 142 about 953
receive a_bit_fielda_remote_sql structure [database remote servers
tools API] 783 about 940
receive_delay a_sql_uint32a_remote_sql structure altering 947
[database tools API] 783 creating 940
ReceiveBufferSize propertySATcpOptionsBuilder deleting 946
class [SQL Anywhere .NET API] 313 external logins 948
recompute a_bit_fieldan_unload_db structure transaction management 954
[database tools API] 833 remote_dir const char *an_unload_db structure
record sets [database tools API] 834
ADO programming 325 remote_output_file_name char *a_remote_sql
RecordsAffected structure [database tools API] 783
propertySARowUpdatedEventArgs class REMOTEPWD
[SQL Anywhere .NET API] 305 using 384
Recordset ADO object remove_encrypted_tables a_bit_fieldan_unload_db
ADO 323 structure [database tools API] 834
ADO programming 326 remove_rollback a_bit_fielda_translate_log
updating data 325 structure [database tools API] 818
Recordset object removeShutdownHook
ADO 324 Java VM shutdown hooks 374
recovery rename_local_log a_bit_fielda_backup_db
distributed transactions 729 structure [database tools API] 754
recovery_bytes a_sql_uint32a_translate_log rename_log a_bit_fielda_backup_db structure
structure [database tools API] 818 [database tools API] 754
recovery_ops a_sql_uint32a_translate_log structure rename_log a_bit_fielda_remote_sql structure
[database tools API] 818 [database tools API] 784
reentrant code rename_log a_bit_fielda_sync_db structure
multithreaded embedded SQL example 437 [database tools API] 802
refresh_mat_view a_bit_fieldan_unload_db replace a_bit_fielda_translate_log structure
structure [database tools API] 833 [database tools API] 818
registering replace_db a_bit_fieldan_unload_db structure
SAP Sybase IQ .NET Data Provider 195 [database tools API] 835
reload_connectparms char *an_unload_db structure reporting functions 880
[database tools API] 833 example 880, 881
reload_db_filename char *an_unload_db structure repserver_users const char *a_translate_log
[database tools API] 833 structure [database tools API] 819
reload_db_logname char *an_unload_db structure request processing
[database tools API] 834 embedded SQL 466
reload_filename const char *an_unload_db requests
structure [database tools API] 834 aborting 473
reload_page_size unsigned shortan_unload_db requirements
structure [database tools API] 834 Open Client applications 618
remote data 943 resend_urgency a_sql_uint32a_remote_sql
structure [database tools API] 784
Programming 1031
Index
Programming 1033
Index
Programming 1035
Index
SAConnectionStringBuilderBase class [SQL SAError class [SQL Anywhere .NET API] SqlState
Anywhere .NET API] this property 257, property 274
261, 314 SAErrorCollection class [SQL Anywhere .NET
SADataAdapter API] Count property 276
obtaining primary key values 182 SAErrorCollection class [SQL Anywhere .NET
SADataAdapter class API] description 275
about 170 SAErrorCollection class [SQL Anywhere .NET
deleting data 175 API] this property 276
inserting data 175 SAException class [SQL Anywhere .NET API]
retrieving data 177, 178 description 276
updating data 175 SAException class [SQL Anywhere .NET API]
SADataAdapter class [SQL Anywhere .NET API] Errors property 277
DeleteCommand property 266 SAException class [SQL Anywhere .NET API]
SADataAdapter class [SQL Anywhere .NET API] Message property 277
description 262 SAException class [SQL Anywhere .NET API]
SADataAdapter class [SQL Anywhere .NET API] NativeError property 278
InsertCommand property 267 SAException class [SQL Anywhere .NET API]
SADataAdapter class [SQL Anywhere .NET API] Source property 278
SelectCommand property 267 SAFactory class [SQL Anywhere .NET API]
SADataAdapter class [SQL Anywhere .NET API] CanCreateDataSourceEnumerator
TableMappings property 268 property 282
SADataAdapter class [SQL Anywhere .NET API] SAFactory class [SQL Anywhere .NET API]
UpdateBatchSize property 268 description 278
SADataAdapter class [SQL Anywhere .NET API] SAFactory class [SQL Anywhere .NET API]
UpdateCommand property 269 Instance field 282
SADataReader class SAInfoMessageEventArgs class [SQL
using 171 Anywhere .NET API] description 282
SADataSourceEnumerator class [SQL SAInfoMessageEventArgs class [SQL
Anywhere .NET API] description 271 Anywhere .NET API] Errors property
SADataSourceEnumerator class [SQL 283
Anywhere .NET API] Instance property SAInfoMessageEventArgs class [SQL
272 Anywhere .NET API] Message property
SADBParametersEditor class [SQL 283
Anywhere .NET API] description 296, SAInfoMessageEventArgs class [SQL
301 Anywhere .NET API] MessageType
SADbType propertySAParameter class [SQL property 283
Anywhere .NET API] 292 SAInfoMessageEventArgs class [SQL
SADefault class [SQL Anywhere .NET API] Anywhere .NET API] NativeError
description 272 property 284
SADefault class [SQL Anywhere .NET API] Value SAInfoMessageEventArgs class [SQL
field 273 Anywhere .NET API] Source property
SAError class [SQL Anywhere .NET API] 284
description 273 SAIsolationLevel propertySATransaction class
SAError class [SQL Anywhere .NET API] Message [SQL Anywhere .NET API] 317
property 274 SAIsolationLevel() enumeration [SQL
SAError class [SQL Anywhere .NET API] Anywhere .NET API] 213
NativeError property 274 sajdbc4.jar
SAError class [SQL Anywhere .NET API] Source loading SQL Anywhere JDBC driver 387
property 274
Programming 1037
Index
SAParameter class [SQL Anywhere .NET API] Size SARowUpdatedEventArgs class [SQL
property 293 Anywhere .NET API] RecordsAffected
SAParameter class [SQL Anywhere .NET API] property 305
SourceColumn property 294 SARowUpdatingEventArgs class [SQL
SAParameter class [SQL Anywhere .NET API] Anywhere .NET API] Command property
SourceColumnNullMapping property 306
294 SARowUpdatingEventArgs class [SQL
SAParameter class [SQL Anywhere .NET API] Anywhere .NET API] description 305
SourceVersion property 294 sasql_affected_rows function (PHP)
SAParameter class [SQL Anywhere .NET API] syntax 566
Value property 295 sasql_close function (PHP)
SAParameterCollection class [SQL syntax 567
Anywhere .NET API] Count property sasql_commit function (PHP)
299 syntax 567
SAParameterCollection class [SQL sasql_connect function (PHP)
Anywhere .NET API] description 295 syntax 567
SAParameterCollection class [SQL sasql_data_seek function (PHP)
Anywhere .NET API] IsFixedSize syntax 568
property 299 sasql_disconnect function (PHP)
SAParameterCollection class [SQL syntax 568
Anywhere .NET API] IsReadOnly sasql_error function (PHP)
property 300 syntax 568
SAParameterCollection class [SQL sasql_errorcode function (PHP)
Anywhere .NET API] IsSynchronized syntax 569
property 300 sasql_escape_string function (PHP)
SAParameterCollection class [SQL syntax 569
Anywhere .NET API] SyncRoot property sasql_fetch_array function (PHP)
300 syntax 570
SAParameterCollection class [SQL sasql_fetch_assoc function (PHP)
Anywhere .NET API] this property 300 syntax 570
SAPermission class [SQL Anywhere .NET API] sasql_fetch_field function (PHP)
description 302 syntax 571
SAPermissionAttribute class [SQL Anywhere .NET sasql_fetch_object function (PHP)
API] description 303 syntax 571
SARowsCopiedEventArgs class [SQL sasql_fetch_row function (PHP)
Anywhere .NET API] Abort property syntax 572
307 sasql_field_count function (PHP)
SARowsCopiedEventArgs class [SQL syntax 572
Anywhere .NET API] description 306 sasql_field_seek function (PHP)
SARowsCopiedEventArgs class [SQL syntax 572
Anywhere .NET API] RowsCopied sasql_free_result function (PHP)
property 307 syntax 573
SARowUpdatedEventArgs class [SQL sasql_get_client_info function (PHP)
Anywhere .NET API] Command property syntax 573
305 sasql_insert_id function (PHP)
SARowUpdatedEventArgs class [SQL syntax 573
Anywhere .NET API] description 304 sasql_message function (PHP)
syntax 574
Programming 1039
Index
Programming 1041
Index
Programming 1043
Index
Programming 1045
Index
Programming 1047
Index
structure packing T
header files 416
table
subscriber_username const char *an_unload_db
a_v4_extfn_table 116
structure [database tools API] 836
table adapter
subscription char *a_syncpub structure [database
Visual Studio 207
tools API] 809
table constraints 968
subtotal rows 847
table context
construction 847
a_v4_extfn_table_context 117
definition 846, 855
fetch_block method 121
NULL values 848
fetch_into method 119
ROLLUP operation 847
rewind method 123
summary information
table functions
CUBE operator 855
_close_extfn method 128
summary rows
_fetch_block_extfn method 127
ROLLUP operation 847
_fetch_into_extfn method 126
supported platforms
_open_extfn method 126
OLE DB 320
_rewind_extfn method 128
suppress_statistics a_bit_fieldan_unload_db
a_v4_extfn_table_func 124
structure [database tools API] 836
table parameterized function 11, 12
Sybase IQ ODBC driver
table UDF 11, 12
driver name 346
Table UDF 13
Sybase Open Client support
table_id a_sql_uint32a_table_info structure
about 617
[database tools API] 811
sync_opt char *a_sync_db structure [database tools
table_list p_namean_unload_db structure [database
API] 803
tools API] 837
sync_params char *a_sync_db structure [database
table_list_provided a_bit_fieldan_unload_db
tools API] 804
structure [database tools API] 837
sync_profile char *a_sync_db structure [database
table_name char *a_table_info structure [database
tools API] 804
tools API] 811
SyncRoot propertySAParameterCollection class
table_pages a_sql_uint32a_table_info structure
[SQL Anywhere .NET API] 300
[database tools API] 811
sys_proc_definer a_bit_fielda_create_db structure
table_used a_sql_uint32a_table_info structure
[database tools API] 765
[database tools API] 812
sys_proc_definer unsigned shortan_upgrade_db
table_used_pct a_sql_uint32a_table_info structure
structure [database tools API] 840
[database tools API] 812
sysinfo a_sysinfoa_db_info structure [database
TableMappings propertySADataAdapter class
tools API] 769
[SQL Anywhere .NET API] 268
sysinfo a_sysinfoan_unload_db structure [database
tables
tools API] 837
creating 968
sysservers system table
creating proxy 964
remote servers 940
GLOBAL TEMPORARY 968
system procedures
remote access 919
HTTP 653
temporary 968
SOAP 653
Tables fieldSAMetaDataCollectionNames class
system requirements
[SQL Anywhere .NET API] 288
SAP Sybase IQ .NET Data Provider 194
tables p_namea_validate_db structure [database
System.Transactions
tools API] 823
using 186
TableViewer
.NET Data Provider sample project 167
TcpOptionsBuilder TimeSpan
propertySACommLinksOptionsBuilder SAP Sybase IQ .NET Data Provider 184
class [SQL Anywhere .NET API] 225 TIMESTAMP data type
TcpOptionsString Open client conversion 619
propertySACommLinksOptionsBuilder totals a_table_info *a_db_info structure [database
class [SQL Anywhere .NET API] 225 tools API] 770
TDS propertySATcpOptionsBuilder class [SQL TPF 11–13
Anywhere .NET API] 314 tracing
temp_dir const char *an_unload_db structure .NET support 196
[database tools API] 837 trans_upload a_bit_fielda_sync_db structure
template_name const char *an_unload_db structure [database tools API] 804
[database tools API] 837 transaction isolation level 390
temporary tables 968 transaction management 954
creating 968 transaction processing
this using the SAP Sybase IQ .NET Data Provider
propertySABulkCopyColumnMappingC 186
ollection class [SQL Anywhere .NET Transaction propertySACommand class [SQL
API] 222 Anywhere .NET API] 238
this propertySAConnectionStringBuilderBase class transaction_logs char *a_remote_sql structure
[SQL Anywhere .NET API] 257, 261, [database tools API] 785
314 transactions
this propertySAErrorCollection class [SQL ADO 326
Anywhere .NET API] 276 application development 161
this propertySAParameterCollection class [SQL autocommit mode 161
Anywhere .NET API] 300 controlling autocommit behavior 161
threads cursors 163
Java in the database 372 distributed 725
multiple SQLCAs 439 isolation level 163
multiple thread management in embedded SQL managing 955
437 OLE DB 326
threads a_sql_uint32a_remote_sql structure remote data access 954
[database tools API] 785 using distributed 728
three-tier computing TransactionScope class
about 725 using 186
architecture 725 triggers a_bit_fielda_remote_sql structure
Distributed Transaction Coordinator 727 [database tools API] 785
distributed transactions 726 troubleshooting
EAServer 727 cursor positioning 138
Microsoft Transaction Server 727 Java in the database methods 372
resource dispensers 727 remote data access 957
resource managers 727 truncate_interrupted chara_truncate_log structure
Time structure [database tools API] 822
time values in .NET Data Provider 184 truncate_log a_bit_fielda_backup_db structure
timeout callback 481 [database tools API] 755
Timeout propertySATcpOptionsBuilder class [SQL truncate_remote_output_file
Anywhere .NET API] 315 a_bit_fielda_remote_sql structure
times [database tools API] 785
obtaining with .NET Data Provider 184 truncation
FETCH statement 434
Programming 1049
Index
interpreting 654 V
jConnect 383
v4 API
session management 648
_close_extfn method 128
SQL Anywhere16 JDBC driver 381
_fetch_block_extfn method 127
supplying variables 675
_fetch_into_extfn method 126
usage_rtn USAGE_CALLBACKa_sync_db
_open_extfn method 126
structure [database tools API] 805
_rewind_extfn method 128
use_fixed_cache a_bit_fielda_sync_db structure
alloc method 109
[database tools API] 805
close_result_set method 110
use_hex_offsets a_bit_fielda_remote_sql structure
fetch_block method 121
[database tools API] 786
fetch_into method 119
use_hex_offsets a_bit_fielda_sync_db structure
get_option method 108
[database tools API] 805
open_result_set method 110
use_hex_offsets a_bit_fielda_translate_log
rewind method 123
structure [database tools API] 820
set_cannot_be_distributed method 112
use_internal_reload a_bit_fieldan_unload_db
valid_data a_bit_fielda_sysinfo structure [database
structure [database tools API] 838
tools API] 810
use_internal_unload a_bit_fieldan_unload_db
Validation() enumeration [database tools API] 750
structure [database tools API] 838
value a_sqlany_data_valuea_sqlany_bind_param
use_relative_offsets a_bit_fielda_remote_sql
structure [SQL Anywhere C API] 528
structure [database tools API] 786
Value fieldSADefault class [SQL Anywhere .NET
use_relative_offsets a_bit_fielda_sync_db structure
API] 273
[database tools API] 805
Value propertySAParameter class [SQL
use_relative_offsets a_bit_fielda_translate_log
Anywhere .NET API] 295
structure [database tools API] 820
value-based window frames 867
used_dialog_allocation a_bit_fielda_sync_db
ascending and descending order 868
structure [database tools API] 805
ORDER BY clause 868
user_name char *a_sync_db structure [database
value-sensitive cursors
tools API] 806
about 151
User-Agent
delete example 145
accessing HTTP headers 641
introduction 144
UserDefinedTypes
update example 146
fieldSAMetaDataCollectionNames class
VAR_POP function 882
[SQL Anywhere .NET API] 288
VAR_SAMP function 882
UserID propertySAConnectionStringBuilder class
VARCHAR data type
[SQL Anywhere .NET API] 258
embedded SQL 427
userlist p_namea_translate_log structure [database
variables
tools API] 820
accessing in HTTP web services 639
UserList() enumeration [database tools API] 749
in SOAP web services 643
userlisttype chara_translate_log structure [database
supplying to HTTP web services 675
tools API] 820
variance functions 881
username char *a_dblic_info structure [database
verbose a_bit_fielda_remote_sql structure
tools API] 773
[database tools API] 786
Users fieldSAMetaDataCollectionNames class
verbose a_bit_fielda_sync_db structure [database
[SQL Anywhere .NET API] 289
tools API] 806
using unbounded windows 868
verbose chara_create_db structure [database tools
utilities
API] 765
return codes 738
verbose charan_unload_db structure [database tools
SQL preprocessor (iqsqlpp) syntax 411
API] 838
Programming 1051
Index
Programming 1053
Index