PSS ID Number: 184559
Article Last Modified on 10/3/2003
The information in this article applies to:
This article was previously published under Q184559
BUG #: 17889 (SQLBUG_65)
37106 (SQLBUG_70)
SYMPTOMS
When using "void *" to map a SQL BINARY column, an access violation (AV)
may occur in Sqlakw32.dll.
WORKAROUND
To work around this problem, use the method described in the following
article in the Microsoft Knowledge Base:
184564
: INF: ESQL: How to Handle Binary Data in ESQL
STATUS
Microsoft has confirmed this to be a problem in Microsoft Embedded SQL
for C Programmer's Toolkit version 6.5.
A supported fix is now available, but has not been fully regression-
tested and should be applied only to systems experiencing this specific
problem. Unless you are severely impacted by this specific problem,
Microsoft recommends that you wait for the next Service Pack that contains
this fix. Contact Microsoft Technical Support for more information.
MORE INFORMATION
The ESQL documentation states in one section that the SQL binary datatype
maps to the void * C datatype. However, using a void * for an input host
variable causes an access violation in Sqlakw32.dll.
The hotfix address two issues:
- Using 'void *' for mapping binary data no longer causes an AV in
sqlakw32.dll.
- Using 'void *' to map input host variables now allows you to input
binary data through static ESQL. Previously, you could only use dynamic
ESQL (as documented).
Note: You could have used static ESQL and used an unsigned char array for
the input host variable in the cases where the data itself did not contain
an embedded 'C' null terminator (0x00), for example, with data that is
something like 0x444942420c4242424242, not like 0x444900000c4242424242. If
the data contains embedded null, it is truncated at the null (this is by
design).
The rest of this article describes the details on how to use 'void *' host
variables in static ESQL to map binary data after applying this hotfix:
After the precompiler generates the .c file, you need to edit it and
replace the '-1' in the sqlasetv API call with the appropriate size for
your void * variable (that you used malloc on). There is no other way of
doing this because you have no idea about the size of the memory buffers
that had malloc run on them. Therefore, it must be provided by you after
nsqlprep precompiles the code. This also comes as a warning message from
the precompiler.
The following is the sample code to show how it works:
EXEC SQL BEGIN DECLARE SECTION;
void * pColBinary;
int iId = 0;
EXEC SQL END DECLARE SECTION;
.
.
.
pColBinary = malloc(10);
memcpy(pColBinary,"\x44\x49\x00\x00\x0c\x42\x42\x42\x42\x42",10);
EXEC SQL
SELECT Id INTO :iId
FROM tblBinary
WHERE ColBinary =[ASCII 160]:pColBinary;
if (SQLCODE != 0)
{
printf(" SQL Code = %li\n", SQLCODE);
printf(" SQL Server Message %li: '%Fs'\n", SQLERRD1,
SQLERRMC);
}
else
printf("The ID is = %d\n", iId);
.
.
.
free(pColBinary);
So in the above example, after you precompile the code, you need to search
through the .c file it generates and replace -1 with 10 in:
sqlasetv(2, 0, 444, -1, (void far *)&pColBinary, (void far *)0, (void far *)0L);
For output data, using an unsigned char array to map the host variable
should work fine in both static and dynamic ESQL, even when data contains
embedded null (0x00). There is no need to use the void * host variable.
Additional query words: data type
Keywords: kbBug kbfix KB184559
Technology: kbAudDeveloper kbSQLServ650 kbSQLServSearch