----- Original Message ----
> From: Richard Hipp <[email protected]>
> To: General Discussion of SQLite Database <[email protected]>
> Sent: Thu, February 21, 2013 11:39:44 AM
> Subject: Re: [sqlite] Ongoing SELECT sees INSERTed rows.
>
> On Thu, Feb 21, 2013 at 1:32 PM, Peter Aronson <[email protected]> wrote:
>
> > SQLite 3.7.15.2, Solaris and Windows (and presumably others). Journal
> > mode is
> > delete, but WAL appears to behave in the same manner.
> >
> > One of my coworkers ran into an infinite loop when accessing SQLite.
> > Essentially
> > an outer select loop was reading records, and an inner select loop was
> > inserting
> > records based on the records found into the same table. The loop never
> > ended as
> > the records inserted showed up in the select. This is not necessarily an
> > error,
> > of course. But if you take the script and the program below which
> > reproduces
> > the problem, add "order by c3" to the select statement, it doesn't happen
> > (presumably because we're reading the materialized temporary table, not
> > the base
> > table at that point). This sort of inconsistency can be an unpleasant
> > surprise.
> >
> > If you look at SQL 92, it has a concept of INSENSITIVE cursors, which
> > causes the
> > cursor to logically (at least) work on a copy of the data, so that changes
> > to
> > the underlying table are not visible. It would be nice if SQLite provided
> > a
> > method to make a insensitive select ("order by rowid" appears to get
> > silently
> > removed by the optimizer as you'd expect) less expensive than performing an
> > otherwise unnecessary order by.
> >
>
> (1) CREATE TEMP TABLE xyz AS SELECT...;
>
> (2) Query the xyz table while doing whatever updates are needed.
>
> (3) DROP TABLE xyz;
>
> The other thing you can do is open two database connections on the same
> database (in WAL mode) and query from one while updating on the other.
>
>
Thanks! The possibility we were wondering about was having an integer primary
key autoincrement column and just exiting the select loop when encountering a
id
greater than the max id at start time (I assume this approach would not be safe
if the integer primary key column was not autoincrementing).
> >
> > Peter
> >
> > create table base1 (c1 integer,c2 text,c3 integer);
> > insert into base1 (c1,c2,c3) values (1,'andrew',10);
> > insert into base1 (c1,c2,c3) values (1,'jeffrey',15);
> > insert into base1 (c1,c2,c3) values (1,'david',20);
> > insert into base1 (c1,c2,c3) values (1,'Jonathan',25);
> >
> > #include <stdio.h>
> > #include <stdlib.h>
> > #include <string.h>
> > #include "sqlite3.h"
> > int main (int argc,
> > char *argv[])
> > {
> > sqlite3 *hdbc;
> > int s3err,rid,c3;
> > sqlite3_stmt *hupdate,*hselect;
> > char sql[256];
> >
> > /* Open our test database (assumed to be named test.db). */
> >
> > s3err = sqlite3_open_v2 ("test.db",
> > &hdbc,
> > SQLITE_OPEN_READWRITE,
> > NULL);
> > if (SQLITE_OK != s3err) {
> > fprintf (stderr,"Unable to open test.db, err = %d\n",s3err);
> > return EXIT_FAILURE;
> > }
> >
> > /* Start a select on base1. */
> >
> > s3err = sqlite3_prepare_v2 (hdbc,
> > "select rowid,c3 "
> > "from base1 "
> > "where c3 < 15 and c1 = 1",
> > -1,
> > &hselect,
> > NULL);
> > if (SQLITE_OK != s3err) {
> > fprintf (stderr,"Unable to prepare select on base1, err = %d\n",s3err);
> > return EXIT_FAILURE;
> > }
> >
> > while ((s3err = sqlite3_step (hselect)) == SQLITE_ROW) {
> > rid = sqlite3_column_int (hselect,0);
> > c3 = sqlite3_column_int (hselect,1);
> > sprintf (sql,"insert into base1 (c1,c2,c3) values
> > (1,'inactive',%d)",c3);
> >
> > /* Insert into base1. */
> >
> > s3err = sqlite3_prepare_v2 (hdbc,
> > sql,
> > -1,
> > &hupdate,
> > NULL);
> > if (SQLITE_OK != s3err) {
> > fprintf (stderr,"Unable to prepare insert on base1, err =
> > %d\n",s3err);
> > return EXIT_FAILURE;
> > }
> >
> > switch (sqlite3_step (hupdate)) {
> > case SQLITE_DONE:
> > case SQLITE_ROW:
> > printf ("%d:",rid);
> > fflush (stdout);
> > sqlite3_finalize (hupdate);
> > break;
> > default:
> > fprintf (stderr,"Error on sqlite3_step for insert, err =
> > %d\n",s3err);
> > return EXIT_FAILURE;
> > }
> > }
> > sqlite3_finalize (hselect);
> > if (SQLITE_DONE != s3err) {
> > fprintf (stderr,"Error on sqlite3_step for select, err = %d\n",s3err);
> > return EXIT_FAILURE;
> > }
> >
> > (void) sqlite3_close (hdbc);
> >
> > return EXIT_SUCCESS;
> > }
> >
> > _______________________________________________
> > sqlite-users mailing list
> > [email protected]
> > http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
> >
>
>
>
> --
> D. Richard Hipp
> [email protected]
> _______________________________________________
> sqlite-users mailing list
> [email protected]
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>
_______________________________________________
sqlite-users mailing list
[email protected]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users