Re: Help! with ESQL cursors
Posted in 1993
dave.snyder@snide.com (Dave Snyder) writes: > > Quoting Bill Foote... > } > } In article <1nh2s6INN4e0@emory.mathcs.emory.edu> dave.snyder@snide.com (Dave Snyder) writes: > } > <...> > } > 5) Open the second cursor with the current array element's stored rowid, fetch > } > the data into local variables, and close the second cursor. > } > } and hope that the record hasn't been deleted. > } > Why? What I didn't mention, but a good programmer always does, is check > the value of sqlca.sqlcode. If the row is gone for whatever reason, you > print a message to that effect. In general in a typical application, yes. The specific question was about a server process that was supposed to deliver a count followed by data. If the server process is, say, using the socket interface and perhaps residing on a different machine, "print an error message" isn't a very clear concept. It could mean: a) issue an error message on some master console somewhere b) return some sort of error code to the requesting process, which would have to be checked for c) return a bunch of NULL values In the specific problem that was the subject of the original posting, it could be considered advantageous (depending on the application) to have the data be a "snapshot" of what the data was when the first query was done -- this simplifies this particular error condition out of existance. I'm not saying that tmpfile() is the only way to go: I'm just saying that this approach has certain advantages in some applications. It's also simple and robust. > > } Out of curiosity... Does db4glgen increase array size linearly or > } geometrically? > } > Memory is realloc'd on an as-needed basis (linearly). Not to beat a dead horse, but I think that I might not have been completely clear in my original post. Both linear and geometric realloc() strategy are "as needed". Here's what I mean by geometric array size increase: foo_type *foos(int index) /* Here, we do the memory management for a dynamic array of type foo_type, where foo_type is a suitable struct. Use: strcpy(foos(237)->name, "boo!"); /* the struct foo_type has a field called "name" that is char[5] or bigger */ */ { static foo_type *array = NULL; static int array_size = 0; /* # entries allocated */ assert(index >= 0); if (array_size == 0) { array_size = max(20, (index+1)); array = malloc(array_size * sizeof(foo_type)); assert(array != (foo_type *) NULL); } if (array_size <= index) { array_size = max((index+1), (array_size * 2)); /* We always at least double the size of the array. This makes filling an array with N elements be O(N) instead of O(N^2) */ array = realloc(array, array_size*sizeof(foo_type)); assert(array != (foo_type *) NULL); } return &(array[index]); } Replace the line "array_size = max((index+1), (array_size * 2))" with "array_size = max((index+1), (array_size + 10))" and you have array size increasing linearly. Of course the actual factors used (2 and 10) are arbitrary, and don't effect the big-O performance of the algorithm. Like I said, this kind of consideration is overkill for the typical database application. It's a lot more important in an application like computer graphics -- if you allocate an array of 40,000 vertices 10 at a time using realloc(), then you'll have problems. -- Bill Foote bill@pds.com PDS Corp, Los Angeles, CA USA uunet!promdist!bill