SQLite3 - how to know if the current row is the last row - sqlite

This is trivial in mysql thanks to mysql_num_rows but no such equivalent is present in sqlite3. Hence the question is how to know if the current row is the last row.
Rearranging like following doesn't help as any previous binding after sqlite3_step is not valid.
sqlite3_prepare_v2()
int fetched = 0;
int last = 0;
while (sqlite3_step(statement) == SQLITE_ROW) {
// this is the previous row
if(fetched) {
process(data, last);
}
fetched = 1;
data = sqlite3_column_text();
}
last = 1;
if(fetched)
process(data, last);
Executing query twice (one with count) is a trivial solution but that's not what I am looking for.
Any ideas? thanks in advance.

SQLite computes the next output row only when needed.
So it is not possible to find out if you can get another row without actually trying to step to that row.
If your code really needs to know whether the current row is the last, you have to make a copy of all the data in the row.

Related

Get cell types when reading and parsing excel files

I am trying to read and parse and excel and some unclear things come into play as usual for me.
Here is what i have:
while (true)
{
comVariantCell1 = cells.item(row, 1).value().variantType();
comVariantCell2 = cells.item(row, 2).value().variantType();
//if an empty cell is found, processing will stop and user will get an error message in order to solve the inconsistency.
if (comVariantCell1 != COMVariantType::VT_EMPTY && comVariantCell2 != COMVariantType::VT_EMPTY)
{
//both cells have values, check their types.
importedLine = conNull();
progress1.setText(strfmt("Importing row %1", row));
if (cells.item(row, 1).value().variantType() == COMVariantType::VT_BSTR)
{
importedLine += cells.item(row, 1).value().bStr();
}
else
{
importedLine += cells.item(row, 1).value().double();
}
importedLine += cells.item(row, 2).value().double();
importedLinesCollection += [importedLine]; //conIns(importedLinesCollection, row - 1, (importedLine));
row++;
}
else
{
info (strFmt("Empty cell found at line %1 - import will not continue and no records were saved.", row));
break;
}
}
Excel format:
Item number Transfer Qty
a100 50.5
a101 10
a102 25
This worked well to check if the cell type is string: COMVariantType::VT_BSTR
but what should i use to check for a real or integer value ?
I am pretty sure in this case, the quantity will be not contain real values but anyway, it could be useful in the future to make the difference between these two types.
I have to mention that, even if i have an int value and I use cells.item(row, 1).value().int() it won't work. I can't see why.
Why do i want to make the difference? Because if it's forbidden to have real values in the quantity column ( at least in my case ), i want to check that and give the user the opportunity to put a correct value in that place and maybe further investigate why that happened to be there.
Take a look on how it is done in \Classes\SysDataExcelCOM\readRow.
It is basically using switch to test the type. This is really boring!
Also take a look on ExcelIO, a class I made some years ago. It reads Excel and returns each row as a container. This is a more high-level approach.
As a last resort you could save the Excel as a tab separated file. Then use TextIO to read the content. This will be at least 10 times faster than using Excel!

How to check specific column exist in datarow?

I came across situation,where columnname for datatable is dynamic.While fetching a data I want to check existence of column.
DataTable table = ds.Table["Sample1"]
if(table.Row.Count > 0)
{
foreach(DataRow dr in table.Rows )
{
if(dr.Table.Column.Contain("DateInfo"))
{
// store value in variable
// first approach
}
if(table.Column.Contain("DateInfo"))
{
// store value in variable
// second approach
}
}
}
Which one is best approach?
Will this be enough:
1st Approach: Which will simply check in an entire DataTable.
datatable.Columns.Contains("column")
2nd Approach: which will check for each row collection in DataTable
dr.Table.Columns.Contains("column")
3rd Approach: Which fetch each columns in DataColumnCollection object and then check if it contains the specific field or not.
DataColumnCollection columns = datatable.Columns;
if (columns.Contains(columnName))
So these all approaches are better in their own way. you can use whatever you find it better.
This is best one
dr.Table.Column.Contain("DateInfo")
foreach loop get single row at a time sometimes if any conditional is possible in this method

Form Running Totals, Ax 2009

Is there an example anywhere of a form that performs running totals in a column located within a grid. The user ordering and filtering of the grid would affect the running totals column.
I can easily perform the above if it was ordering only by transaction date, but including the user ordering and filtering I presume that we would have to use the datasource range() and rangecount() functions (see SysQuery::mergeRanges() for an example) then iterate over these to apply the filtering, then include the dynalinks. The same for the ordering, albeit this is now more complicated.
Any suggestions appreciated. Any appreciations suggested (as in: vote the question up!).
You could implement it as a form datasource display method using this strategy:
Copy the form's datasource query (no need for SysQuery::mergeRanges):
QueryRun qr = new QueryRun(ledgerTrans_qr.query());
Iterate and sum over your records using qr, stop after the current record:
while (qr.next())
{
lt = qr.getNo(1);
total += lt.AmountMST;
if (lt.RecId == _lt.RecId)
break;
}
This could be made more performant if the sorting order was fixed (using sum(AmountMST) and adding a where constraint).
Return the total
This is of cause very inefficient (subquadratic time, O(n^2)).
Caching the results (in a map) may make it usable if there are not too many records.
Update: a working example.
Any observations or criticisms to the code below most welcome. Jan's observation about the method being slow is still valid. As you can see, it's a modification of his original answer.
//BP Deviation Documented
display AmountMST XXX_runningBalanceMST(LedgerTrans _trans)
{
LedgerTrans localLedgerTrans;
AmountMST amountMST;
;
localLedgerTrans = this.getFirst();
while (localLedgerTrans)
{
amountMST += localLedgerTrans.AmountMST;
if (localLedgerTrans.RecId == _trans.RecId)
{
break;
}
localLedgerTrans = this.getNext();
}
return amountMST;
}

SQLite seek question

I'm using SQLite version 3 to run the following code.
//Run SQL SELCT query
sqlite3_prepare16_v2("SELECT * FROM table_name");
sqlite3_step();
//Need to review results in several iterations
for(int i = 0; i < n; i++)
{
//Seek to beginning
sqlite3_reset();
do
{
//Get values
sqlite3_column_int();
...
sqlite3_column_text16();
}
while(sqlite3_step() == SQLITE_ROW);
}
But for some reason the first batch of data I get is all 0's. What am I not doing correct in the code above?
Assuming what you are showing is pseudocode since you're missing many arguments to the sqlite3 funcitons...
You need a sqlite3_step after sqlite3_reset and before getting the first row of values.
You can change your do {...} while(sqlite3_step() == SQLITE_ROW) to a while(sqlite3_step() == SQLITE_ROW)...} to accomplish that.
This will also eliminate the need to step immediately after the sqlite3_prepare16_v2

Grid View Comparison

I want to compare rows of two grid views.GW1 and GW2.
When I click a Search Button ,I want to check the Values in the GW2,and if GW1 and GW2 have same PayID ,EmpID,then that specific row of GW1 must be disabled
Thanks
int i = 0;
while(i < GridView1.Rows.Count && i < GridView2.Rows.Count)
{
if(
GridView1.Rows[i].Cells[column for pay ID].Text == GridView2.Rows[i].Cells[column for pay ID].Text &&
GridView1.Rows[i].Cells[column for emp ID].Text == GridView2.Rows[i].Cells[column for emp ID].Text))
{
GridView1.Rows[i].Enabled = false;
}
i++;
}
Only way I can think of is to loop through table one and search for similar rows in table two. This is how you can do this:
Loop through the Table 1.
Use DataTable.Select to find if there are rows with same PayID and EmpID in Table 2.
If the method returns more than 0 rows, then disable the rows.
Apart from this, you can also think about writing/searching a method which can give you intersection of two tables. If these two columns are priamry keys, then this will work. If not, then you will need to tweak the code as per your need.
do something like this, its not the actual code, but you will have the idea.
for i=0 to gw1rowscount-1
for j=0 to gw2rowscount-1
if gw1(i)(column1)=gw2(j)(column1) and gw1(i)(column2)=gw2(j)(column2) then
end if
next
next

Resources