Decoding and Encoding SQLLEN
The sqllen field of the sqlvar contains different values based on the sqltype of the column. For all data types except DECIMAL and NUMERIC, the value contained in sqllen is the actual length of the column.
The sqllen for DECIMAL and NUMERIC types contains the precision, scale and length (identical to precision) in the following format:
Byte 0 - Precision / Length
Byte 1 - Scale
Byte 2 - Scale
Byte 3 - Precision / Length
This format ensures that an application program can be moved between big-endian and little-endian platforms without change and ensures that the appropriate byte order is maintained.
There are two methods available to decode and encode SQLLEN.
1. (Preferred method) Use the ACEAPI Utility Functions 'SAGQDECO' and 'SAGQENCO'. These functions can be called from applications written in any supported programming language. Please see the section 'ACEAPI Utility Functions' for more information regarding the usage of these two functions.
2. C and C++ users can use macros which are defined in the ACEAPI header file (aceapic.h).
The sqllen can be decoded into precision, scale and length variables by using the macro DECODE_PRECISION_SCALE_LENGTH.
The sqllen can be encoded with precision, scale and length by using the macro ENCODE_PRECISION_SCALE_LENGTH.
When encoding sqllen, it is essential that ALL four bytes are correctly filled if the above macros are not being used, for example when the application is written in a language other than "C".
The following SQLTYPES require decoding or encoding of the sqllen:
SQL_TYP_DECIMAL
SQL_TYP_NUMERIC
SQL_TYP_NUMERIC_LD
SQL_TYP_NUMERIC_TR
SQL_TYP_NUMERIC_SLD
SQL_TYP_NUMERIC_STR
SQL_TYP_NUMERIC_BINARY
SQL_TYP_NUMERIC_BIN_BE
SQL_TYP_NDECIMAL
SQL_TYP_NNUMERIC
SQL_TYP_NNUMERIC_LD
SQL_TYP_NNUMERIC_TR
SQL_TYP_NNUMERIC_SLD
SQL_TYP_NNUMERIC_STR
SQL_TYP_NNUMERIC_BINARY
SQL_TYP_NNUMERIC_BIN_BE
The sqllen field in the sqlvar should remain encoded and not be modified. If the length of the column is required, when allocating storage for example, the decoded values sqlprec or sqllength should be used and not the sqllen itself.
Examples
Here is an example how to decode and encode 'sqllen' for DECIMAL and NUMERIC type columns. The DECODE_PRECISION_SCALE_LENGTH and ENCODE_PRECISION_SCALE_LENGTH macros are defined in the ACEAPI header file (aceapic.h).
int sqlprec; /* Precision */
int sqlscale; /* Scale */
int sqllength; /* Length */
if (sqlda->sqlvar[column].sqltype == SQL_TYP_DECIMAL
|| SQL_TYP_NUMERIC
|| SQL_TYP_NUMERIC_LD
|| SQL_TYP_NUMERIC_TR
|| SQL_TYP_NUMERIC_SLD
|| SQL_TYP_NUMERIC_STR
|| SQL_TYP_NUMERIC_BINARY
|| SQL_TYP_NUMERIC_BIN_BE
|| SQL_TYP_NDECIMAL
|| SQL_TYP_NNUMERIC
|| SQL_TYP_NNUMERIC_LD
|| SQL_TYP_NNUMERIC_TR
|| SQL_TYP_NNUMERIC_SLD
|| SQL_TYP_NNUMERIC_STR
|| SQL_TYP_NNUMERIC_BINARY
|| SQL_TYP_NNUMERIC_BIN_BE)
{
DECODE_PRECISION_SCALE_LENGTH(sqlda->sqlvar[column].sqllen,
sqlprec,
sqlscale,
sqllength);
/*
Allocate storage using the sqllength returned by the macro DECODE_PRECISION_SCALE_LENGTH.
*/
sqlda->sqlvar[column].sqldata.host_address = calloc(1, sqllength);
..
ENCODE_PRECISION_SCALE_LENGTH(sqlda->sqlvar[column].sqllen,
sqlprec,
sqlscale,
sqllength);
}