Retrying a fetch after an error, without restarting the whole loop?

Retrying a fetch after an error, without restarting the whole loop?

am 09.11.2006 00:29:37 von bart.lateur

I've been saving picture files that had been stored in a blob field in
an MS-Access database (aka an "OLE Object") to files, and I've bumped
onto some LongReadLen related problems: through trial and error I
finally succeeded in making LongreadLen long enough to reliable extract
all the files. (in Access, the function LEN on such a field reports a
size that's half the number of bytes. Apparently it mistakes it for
Unicode text. I haven't found a better suited function than LEN, though
I haven't searched hard).

Anyway; as this was a process of several minutes, it took some time to
fix the script and start all over.

So I was wondering these two things:

1) What's the best way to temporarily disable RaiseError when I want to
have it enabled for the rest of the script? Say, for one SQL statement?

And 2), in a fetch loop, is it possible to adjust a property like
{ReadLongLen}, and retry the same fetch without restarting the whole
loop? Because this error typically happened several minutes into the
loop.

I think these 2 questions don't mix well. Oh well.

--
Bart.

Re: Retrying a fetch after an error, without restarting the whole loop?

am 09.11.2006 08:26:02 von jonathan.leffler

------=_Part_44222_14798489.1163057162399
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

On 11/8/06, Bart Lateur wrote:
>
> I've been saving picture files that had been stored in a blob field in
> an MS-Access database (aka an "OLE Object") to files, and I've bumped
> onto some LongReadLen related problems: through trial and error I
> finally succeeded in making LongreadLen long enough to reliable extract
> all the files. (in Access, the function LEN on such a field reports a
> size that's half the number of bytes. Apparently it mistakes it for
> Unicode text. I haven't found a better suited function than LEN, though
> I haven't searched hard).
>
> Anyway; as this was a process of several minutes, it took some time to
> fix the script and start all over.
>
> So I was wondering these two things:
>
> 1) What's the best way to temporarily disable RaiseError when I want to
> have it enabled for the rest of the script? Say, for one SQL statement?


$sth->{RaiseError} = 0;

Or:

$dbh->{RaiseError} = 0;
$dbh->do("something that might fail");
$dbh->{RaiseError} = 1;

And 2), in a fetch loop, is it possible to adjust a property like
> {ReadLongLen}, and retry the same fetch without restarting the whole
> loop? Because this error typically happened several minutes into the
> loop.


Highly unlikely. The data has been fetched - and truncated. There's not
usually a way to refetch the same row - unless you have a scroll cursor, and
DBI doesn't have support for those.

--
Jonathan Leffler #include
Guardian of DBD::Informix - v2005.02 - http://dbi.perl.org
"I don't suffer from insanity - I enjoy every minute of it."

------=_Part_44222_14798489.1163057162399--

RE: Retrying a fetch after an error, without restarting the whole loop?

am 09.11.2006 15:43:03 von Philip.Garrett

Jonathan Leffler wrote:
> On 11/8/06, Bart Lateur wrote:
>>=20
[snip]
>>=20
>> 1) What's the best way to temporarily disable RaiseError when I want
>> to have it enabled for the rest of the script? Say, for one SQL
>> statement?=20
>=20
> $sth->{RaiseError} =3D 0;
>=20
> Or:
>=20
> $dbh->{RaiseError} =3D 0;
> $dbh->do("something that might fail");
> $dbh->{RaiseError} =3D 1;

In situations where I want RaiseError (or AutoCommit, or whatever) to be
reset once a certain piece is done, I use the "local" keyword.

This ensures that:
1) The flag always gets reset, even if something in that code
block dies, and
2) The value is always what it used to be, without you having to save
the old value in a temp variable.

# e.g.
{
local $dbh->{RaiseError} =3D 0;
$dbh->do("something that might fail"); =20
$obj->operation(); # this dies, but RaiseError is still reset
}

Regards,
Philip

Re: Retrying a fetch after an error, without restarting the whole loop?

am 09.11.2006 21:18:48 von bart.lateur

On Wed, 8 Nov 2006 23:26:02 -0800, Jonathan Leffler wrote:

>>And 2), in a fetch loop, is it possible to adjust a property like
>> {ReadLongLen}, and retry the same fetch without restarting the whole
>> loop? Because this error typically happened several minutes into the
>> loop.
>
>
>Highly unlikely. The data has been fetched - and truncated. There's not
>usually a way to refetch the same row - unless you have a scroll cursor, and
>DBI doesn't have support for those.

I can see that. Well I'm thinking of the following solution next:
retrieve extra data to identify the row that went wrong and collect
them, keep going on with the rest of the records, and individually fetch
the previously failed ones afterwards.

After a failure, I can go on with the next records, can't I? And
changing ReadLongLen, is that acceptable for the remainder of the loop?

--
Bart.

Re: Retrying a fetch after an error, without restarting the whole loop?

am 09.11.2006 22:14:19 von jonathan.leffler

------=_Part_58261_17948015.1163106859442
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

On 11/9/06, Bart Lateur wrote:
>
> On Wed, 8 Nov 2006 23:26:02 -0800, Jonathan Leffler wrote:
> > Bart Lateur asked:
> >>And 2), in a fetch loop, is it possible to adjust a property like
> >> {ReadLongLen}, and retry the same fetch without restarting the whole
> >> loop? Because this error typically happened several minutes into the
> >> loop.
> >
> >Highly unlikely. The data has been fetched - and truncated. There's not
> >usually a way to refetch the same row - unless you have a scroll cursor,
> and
> >DBI doesn't have support for those.
>
> I can see that. Well I'm thinking of the following solution next:
> retrieve extra data to identify the row that went wrong and collect
> them, keep going on with the rest of the records, and individually fetch
> the previously failed ones afterwards.
>
> After a failure, I can go on with the next records, can't I? And
> changing ReadLongLen, is that acceptable for the remainder of the loop?



That works - I've used it in (non-Perl) code for aeons (dating back to
1986). The primary demerits are (1) two fetches for each row, and (2)
establishing the unique identifier column or columns for the data.

And yes, I can think of no reason why a driver that honours ReadLongLen
would not adapt to changed values as the loop continues. Since
DBD::Informix doesn't pay attention to ReadLongLen in the first place, it
isn't much use looking at that code - and other driver writers would have to
answer for their code.

--
Jonathan Leffler #include
Guardian of DBD::Informix - v2005.02 - http://dbi.perl.org
"I don't suffer from insanity - I enjoy every minute of it."

------=_Part_58261_17948015.1163106859442--