How to seek stmt to row number in SQLite3? - c++

I don't find the way to seek in a sqlite3_stmt.
I have an input view to let user input and execute SQL, but maybe the result has a huge amounts of records. I just want to display a piece of the result.
E.g.: I have 20000 rows in stmt. But I want to display the first 2000 rows (0-2000). When the user clicks the next button, I want to display the second 2000 rows (2000-4000). When the user click the previous button, I want the display to rewind. So I want seek in the stmt. But I cannot find some SQLite3 function to seek the stmt.
I use the C/C++ interface.

SQLite computes the returned values of a statement on the fly.
The only way to move to another row is to call sqlite3_step; it is not possible to move backwards.
You could read all rows and save them somewhere, but this becomes inpractical when there are too many of them.
You could execute separate queries with the LIMIT/OFFSET clause to restrict the result to the current window.
However, this becomes inefficient when the offset value becomes bigger because SQLite still has to compute all those records.
To implement a scrolling cursor, you should save the last(/first) record of the page, and ask the database to return the next(/previous) 2000 records after(/before) that record.
This is explained in detail in the SQLite wiki.

Related

How can I loop only the page records from the selected one to the latest?

I'm trying to loop all records displayed in a page, from the selected one to the end of the rows:
For example here, as I'm selecting only the 5th row it will loop through 5th and 6th row (as there are no more rows below)
What I've been trying is this:
ProdOrderLine := Rec;
REPEAT
UNTIL ProdOrderLine.NEXT = 0;
But it will loop through all records in the table which are not even displayed in the page...
How can I loop only the page records from the selected one to the latest?
Try Copy instead of assignment. Assignment only copies values of there field from one instance of record-variable to another, it died not copy filters or keys (sort order).
Alas, I have to mention that this is uncommon scenario to handle records like this in BC. General best practice approach would be to ask user to select all the records he or she needs with the shift+click, ctrl+click or by dragging the mouse. In that case you will use SetSelectionFiler to instantly grab ask the selected records.
This is how it works across the system and this how user should be taught to work. It is a bad idea to add a way to interact with record that only works in one page in the whole system even if users are asking for it bursting into tears. They probably just had this type of interaction in some other system they worked with before. I know this is a tough fight but it worth it. It is for the sake of stability (less coding = less bugs) and predictability (a certain way of interaction works across all the pages) of the system.

How to find unsaved rows in a free-jqgrid?

This may be a strange question. But I encounter such a situation in my implementation. I have three free-jqgrid implementation in a single page. And I have, say 5 records in each. In the first grid, I open row number 2 for editing, do some modification to the columns but didn't click on save-icon to save the changes.
Then I jump to the second grid and open up say row number 4 for editing and make some modifications and don't save that also.
After all the grids, I have a button(say, a "Save" button) at the bottom of the page. Once this button is clicked, I need to validate the above grids and show a validation message that "You have some unsaved data in the grids" how to do this in free-jqgrid???
If that is possible, the next requirement is like, I have to save such unsaved data in the grids automatically - (without waiting for the user to click save for each edited row in each grid) to the db. Is it possible with free-jqgrid? If yes, please share me some example or suggest me how shall I achieve this?
This is is just a hint and do not know if in free-jqGrid this is still available.
When the inline editing is on - a grid parameter savedRow (array of objects) stores the original data of the row(s). In case the user cancel editing the row is restored from this parameter and in case of saving it is deleted.
The idea is simple you can check if this this array is not empty to determine which row is in edit mode and in case the user push a external button you can get the id from savedRow parameter and call saveRow methodto save the unsaved data.
I note again - this is just valid if this parameter is still available in free-jqGrid.

Disable QSql(Relational)TableModel's prefetch/caching behaviour

For some (well, performance) reason, Qt's "model" classes only fetch 256 rows from the database so if you want to append the row to the end of the recordset, you, apparently, must do something along the lines of
while (model->canFetchMore()) {
model->fetchMore();
}
This does work and when you do model->insertRow(model->rowCount()) afterwards, the row is, indeed, appended after the last row of the recorset.
There are various other problems related to this behaviour, such as when you insert or remove rows from the model, the view that renders it gets redrawn with only 256 rows showing and you must manually make sure, that the missing rows are fetched again.
Is there a way to bypass this behaviour altogether? My model is very unlikely to display more, than, say, 1000 rows, but getting it to retrieve those 1000 rows seems to be a royal pain. I understand, that this is a great performance optimization if you have to deal with larger recordsets, but for me it is a burden rather than a boon.
The model needs to be writable so I can't simply use QSqlQueryModel instead of QSqlRelationalTableModel.
From the QSqlTableModel documentation:
bool QSqlTableModel::insertRecord ( int row, const QSqlRecord & record )
Inserts the record after row. If row is negative, the record will be appended to the end.
Calls insertRows() and setRecord() internally.
Returns true if the row could be inserted, otherwise false.
See also insertRows() and removeRows().
I've not tried yet, but I think that it's not necessary to fetch the complete dataset to insert a record at the end.

Looping through data over multiple pages in Django

I'm trying to find the best way to go about my problem and I would love your input. I am trying to allow users to scan multiple barcodes into a text area. After they are submitted they are split into an array. The user then inputs how many iterations of each value in the array are to be inserted into a MySQL database. I've achieved this using PHP and session variables, looping through the array one step at a time. With Django I've found it a little more difficult and I am wondering if I should just have a "temporary" table in my database that gets refilled with the values from the array of barcodes. The following pages then pull each value from the table instead of using any sort of session variables.
Edit:
I apologize for the confusing question. Let me try and clear it up a bit:
I need to render a view based on each value in the user-submitted array. When it is first submitted, a view is rendered for the first value. When the user hits "Next" a view will be rendered for the second value in the array, and so on.
As for the database issue, each value can have two "types." The user will declare how many of each type is added to the database in each of the views I am trying to render.
Thank you.
this is nothing about django.
forget that temporary table.
add a field "filled" to ur table
select 1st not-filled row, and show "refill" page by this row
then update user input number back to db, set "filled" to "true" at same time.
You probably can port your PHP solution using a Django session object.
I'm not sure if that "one item at a time" is a feature or a "it was easier to code that way" thing, but in the second case - you may want to use Django Formsets to display all items at once and avoid looping through the array.

Size of data obtained from SQL query via ODBC API

Does anybody know how I can get the number of the elements (rows*cols) returned after I do an SQL query? If that can't be done, then is there something that's going to be relatively representative of the size of data I get back?
I'm trying to make a status bar that indicates how much of the returned data I have processed, so I want to be somewhere relatively close. Any ideas?
Please note that SQLRowCount only returns returns the number of rows affected by an UPDATE, INSERT, or DELETE statement; not the number of rows returned from a SELECT statement (as far as I can tell). So I can't multiply that directly to the SQLColCount.
My last option is to have a status bar that goes back and forth, indicating that data is being processed.
That is frequently a problem when you wan to reserve dynamic memory to hold the entire result set.
One technique is to return the count as part of the result set.
WITH
data AS
(
SELECT interesting-data
FROM interesting-table
WHERE some-condition
)
SELECT COUNT(*), data.*
from data
If you don't know beforehand what columns you are selecting
or use a *, like the example above,
then number of columns can be selected out of the USER_TAB_COLS table
SELECT COUNT(*)
FROM USER_TAB_COLS
WHERE TABLE_NAME = 'interesting-table'
SQLRowCount can return the number of rows for SELECT queries if the driver supports it. Many drivers dont however, because it can be expensive for the server to compute this. If you want to guarantee you always have a count, you must use COUNT(*), thus forcing the server into doing the potentially time consuming calculation (or causing it to delay returning any results until the entire result is known).
My suggestion would be to attempt SQLRowCount, so that the server or driver can decide if the number of rows is easily computable. If it returns a value, then multiply by the result from SQLNumResultCols. Otherwise, if it returns -1, use the back and forth status bar. Sometimes this is better because you can appear more responsive to the user.