Subject Re: API: Retrieve/fetch numerical data from database (like an integer/long)
Author nitaligavino <Dan.Crea@apropos.com>
Hello Henrik:

At some level however, I would expect, even the Workbench / IBO use
the API. I wonder if there is some sort of data mangling going on
during the insertion and then an un-mangling when retrieved?

From the database prospective the metadata for the table does not
change. So if the table MyTable has two columns, X and Y, and both
are say integers, then calling describe should report the column
types as xsqlvar.sqltype == SQL_LONG, or 496. So fetching the data
should just give you a 4-byte blob of integer data. The question
then would be is the data in this 4-byte blob really integer data?

Have you tried using an interactive SQL tool, e.g., IBConsole, to do
a QUERY statement to see if the data comes back correctly or not?
Also, who is doing the insert? Can the inserter be putting in junk?

Regards,
Dan


--- In ib-support@yahoogroups.com, "Henrik Sitter"
<henrik.sitter@e...> wrote:
> Hi, Dan.
>
> Thanks a lot for your help. I have tried your code, and basically
it's
> like mine. So they return the same results... when retrieving text
it
> works like it should, but not when it comes to numerical data.
>
> What I forgot to tell you, is that the database is created in
Firebird
> Workbench that I think use IBO. It might be that Firebird Workbench
> (IBO) stores numbers in a special format that creates my problem.
>
> If you have any input on this, I'll be more than happy.
>
> Well, thanks again for your support :)
>
> Henrik
>
>
> -----Original Message-----
> From: nitaligavino <Dan.Crea@a...> [mailto:Dan.Crea@a...]
> Sent: Thursday, January 23, 2003 6:15 PM
> To: ib-support@yahoogroups.com
> Subject: [ib-support] Re: API: Retrieve/fetch numerical data from
> database (like an integer/long)
>
> Hello:
>
> Sorry Henrik, I was unable to follow your code snip-it so I don't
> have a suggestion on your specific code. However, I have included
> some code that I use to allocate the XSQLDA structure after calling
> describe, isc_dsql_describe(.), and before calling isc_dsql_fetch
> (.). Maybe this will help you:
>
> Once I have allocated the necessary storage I then pass the XSQLDA
to
> the isc_dsql_fetch(.) to get the results.
>
>
> I first call this helper to allocate an XSQLDA structure to hold
the
> result set:
>
> bool IBRecord::Helper_AllocCS(XSQLDA **pDataObj, AT_CUSHORT
usFields)
> {
> // Don't re-allocate if we have enough space already
> if(*pDataObj && (usFields <= (*pDataObj)->sqln))
> return(true);
>
> // Allocate control storage in bytes
> if(usFields > 0 && (*pDataObj = (XSQLDA *)new char
> [XSQLDA_LENGTH(usFields)]))
> {
> // Fill in the version and size
> (*pDataObj)->version = SQLDA_VERSION1;
> (*pDataObj)->sqln = usFields; // Number of
> elements in sqlvar array
>
> // Clear the sql variants being pointed to so we have
> a known state
> // Since we have one contiguous buffer we can simply
> clear from the start
> // of the sqlvar structures through the end
> memset((void *)(*pDataObj)->sqlvar, 0, (usFields *
> sizeof(XSQLVAR)));
> return(true);
> }
>
> return(false);
> }
>
> After the XSQLDA structure is allocated, a call to this method is
> made, I loop through the described result set to properly allocate
> the variant storage based on the column's described type and null-
> ability:
>
> bool IBRecord::Helper_AllocVS(XSQLDA **pDataObj)
> {
> if(*pDataObj)
> {
> // Allocate the needed storage
> for(int iAlloc=0;iAlloc < (*pDataObj)->sqld;iAlloc++)
> {
> // Get a pointer to the variant
> XSQLVAR *pSqlVar = &(*pDataObj)->sqlvar
> [iAlloc];
>
> // Coerce the type from a varying to a text
> switch(pSqlVar->sqltype)
> {
> // Set the varying to NOT NULL text
> case SQL_VARYING:
> pSqlVar->sqltype = SQL_TEXT;
> break;
>
> // Set the varying to nullable text
> case SQL_VARYING + 1:
> pSqlVar->sqltype = SQL_TEXT +
> 1;
> break;
> };
>
> // Allocate sqllen bytes, if we fail then
> return false
> if((pSqlVar->sqldata = new char[pSqlVar-
> >sqllen]) == 0)
> {
> // Free anything that might have been
> allocated
> Helper_FreeVS(pDataObj);
> return(false);
> }
>
> // See if we need to allocate space for the
> null indicator flag
> if(pSqlVar->sqltype & 1)
> pSqlVar->sqlind = new short;
>
> }
>
> return(true);
> }
>
> return(false);
> }
>
> Best regards,
> Dan
> --- In ib-support@yahoogroups.com, "Henrik Sitter"
> <henrik.sitter@e...> wrote:
> > Hello,
> >
> > I'm working on and off with the Firebird API, and right now I'm
> trying
> > to retrieve/fetch data from my test database.
> >
> > As long as the data is stored as VarChar or char, everything
works
> like
> > it should, but when it's stored as numerical data (like an
> integer), the
> > database returns just BS.
> >
> > In the coercing and allocating part of my code I use (I suspect
> > something is wrong here):
> >
> > #define ALIGN(ptr, n) ((ptr + n - 1) & ~(n - 1))
> > char *r_buffer, *rec_buffer;
> > .
> > .
> > case SQL_LONG:
> > r_buffer = (char *)malloc(sizeof(long)+sizeof(int));
> > rec_buffer = (char *)ALIGN((long)r_buffer, (sizeof(long)+sizeof
> (int)));
> > var->sqldata = (char *)((long)rec_buffer);
> > break;
> > .
> > .
> >
> > In the fetching part I use (this part works, at least when
fetching
> char
> > and VarChar):
> >
> > .
> > .
> > int fetch_stat;
> > while ((fetch_stat = isc_dsql_fetch(status_vector, &st1, 1,
> my_xsqlda))
> > == 0)
> > {
> > for (i = 0; i < my_xsqlda->sqld; i++)
> > {
> > // process_column is a function that prints the content of
> > my_xsqlda->sqlvar[i] to the console.
> > process_column(&(my_xsqlda->sqlvar[i]));
> > }
> > }
> > .
> > .
> >
> > Anybody have a clue?
>
>
> To unsubscribe from this group, send an email to:
> ib-support-unsubscribe@egroups.com
>
>
>
> Your use of Yahoo! Groups is subject to
> http://docs.yahoo.com/info/terms/