Subject | Re: [ib-support] Re: Number of Rows updated |
---|---|
Author | Ann Harrison |
Post date | 2001-01-26T23:04:17Z |
At 03:53 PM 1/26/2001 -0600, Jason Lee wrote:
Jason Lee wrote,
I'm finding.
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.
Jason Lee wrote,
> >> I need to know if any rows were affected by a given update or deleteThat was terse. But not as terse as the documentation
> >> statement.
>Ann Harrison wrote:
> >
> > Look at the SQL statement info call.
I'm finding.
>I'm looking at this call now, and then type I need to pass would appearRight.
>to be isc_info_sql_records, but that's a total guess.
> Assuming this isRight.
>right type to pass (to isc_dsql_sql_info(), right? ;)
>I'm not sure howFrom the IBPhoenix web site (http://ibphoenix.com/doc0494.html) The
>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.
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.