in reply to DBI forgets last record

This is actually a common logic problem, which can easily happen in any sort of programing, not just sql programming (or to be more precise, not just a problem with a particular sql interface package.)

As a general thinking, when you operate on an object, basically there are two types of operations:
  1. TESTINGS, this kind of operation does not alter the target object and any of its attribute(s). For exacmple, the eof() function of a file handler. When you call eof(), you SIMPLY OBSERVE whether the end of a file has been reached, there is no harm to the file descriptor at all.
  2. MODIFICATIONS, this kind of operation alters the target object or its attribute(s).

    You may wondering how can this description fit in the current question/situation, as you just want to select from the database, which is only a kind of observation, and thinking it does not modify the database at all.

    This thinking is half correct, and half wrong.

    Yes, You didn't alter the database, and that is 100% true. However, you touched the ACTIVE DATASET, which is a different object. You first create a prepared sql statement, and then you call execute, the moment you call execute, an object called ACTIVE DATASET was created on the database side. It is a dataset that contains all the rows you selected. (This is not done at the time, when you fetch the rows. When you fetch, you are not fetching from the database, instead you are fetching from the ACTIVE DATASET.)

    Now, there is a "pointer" points to the current row of the the ACTIVE DATASET, which will be returned to you next time when you fetch.

    In this sense, fetch is NOT a TESTING, but rather a MODIFICATION, as it modifies the pointer that points to the current row of the ACTIVE DATASET.

Now go back to my general thinking, this actually reminds us that, when we create our own packages, it is always nice to provide some pure testing functions, so that the user of our packages have more freedom, and can code their logic more nicely.