Subject Re: [ib-support] Re: Number of Rows updated
Author Ann Harrison
At 03:53 PM 1/26/2001 -0600, Jason Lee wrote:
Jason Lee wrote,

> >> I need to know if any rows were affected by a given update or delete
> >> statement.
>Ann Harrison wrote:
> >
> > Look at the SQL statement info call.

That was terse. But not as terse as the documentation
I'm finding.

>I'm looking at this call now, and then type I need to pass would appear
>to be isc_info_sql_records, but that's a total guess.

Right.

> Assuming this is
>right type to pass (to isc_dsql_sql_info(), right? ;)

Right.

>I'm not sure how
>to interpret the results. Here's what I'm getting (in hex dump form):
>
>17 1D 00 0F 04 00 00 00 00 00 10 04 00 00 00 00 00 04 00 00 00 00 00 0E
>04 00 00 00 00 00 01 01
>
>The buffer I'm passing is 256 chars long. That should be long enough,
>but that's also a total guess.

From the IBPhoenix web site (http://ibphoenix.com/doc0494.html) The
article actually describes the database info call but the mechanism
is the same.

When InterBase API function calls return results in a result buffer,
the buffer usually has the following format:

byte 0 - topic (a 1 byte entry)
byte 1 - length of result (a 2 byte entry)
byte 3 - result (a variable length entry)
byte m - next topic
byte m+1 - length of result
byte m+3 - result
byte n - next topic

One important fact that is omitted from the extract above is
that the length is returned in a generic form based on VAX/VMS.
When you look at a length word, you must pass it through an
api function called isc_vax_integer (p, n), where p is a pointer
to the first byte and n is the number of bytes. The function
returns a longword. Another function, isc_portable_integer, returns
a 64 bit integer. Either is ok.




Here's some code from isql. The code is pretty embarassing, but
it does work.

SCHAR count_buffer[33];
UCHAR count_is, count_type;
SLONG count;
static SCHAR count_info [] = { isc_info_sql_records };

if (Docount)
{
count_type = 0;
count = 0;

if (statement_type == isc_info_sql_stmt_update)
count_type = isc_info_req_update_count;

if (statement_type == isc_info_sql_stmt_delete)
count_type = isc_info_req_delete_count;

/* Skip selects, better to count records incoming later */

if (statement_type == isc_info_sql_stmt_insert)
count_type = isc_info_req_insert_count;

if (count_type)
{
isc_dsql_sql_info (isc_status, &Stmt, sizeof (count_info),
count_info, sizeof (count_buffer), count_buffer);

for (p = count_buffer + 3; *p != isc_info_end; )
{
count_is = *p++;
l = gds__vax_integer (p, 2);
p += 2;
count = gds__vax_integer (p, l);
p += l;
if (count_is == count_type)
break;
}
/* */
sprintf (outfile, "Records affected: %ld%s", rec_count,
NEWLINE);
}
}

Here's a slightly better version:

for (d = buffer; *d != isc_info_end; )
{
item = *d++;
length = isc_vax_integer (d, 2);
d += 2;
if (item == count_type)
{
rec_count = gds__vax_integer (d, length);
break;
}
else if (item = isc__info_error):
break;
}
d += length;
}
if (rec_count)
sprintf (outfile, "Records affected: %ld%s", rec_count, NEWLINE);


Hope you find this more enlightening.


Regards,

Ann
www.ibphoenix.com
We have answers.