SQL delete leaving the ID not deleted - java

When I use deleteRow method it deletes all the values of a row(imagine row 2 of a total 0f 5 rows) but when I use my getLastID method it still returns the lastID 5 as if there still are 5 numbers. Here are my methods
Method to delete all the values in the row whit the id given
public Integer deleteRow(String id){
return database.delete(TABLE_NAME,"ID=?",new String[]{id});
}
Method to getLastID
public int getLastId() {
String query = "SELECT MAX(id) AS max_id FROM " + TABLE_NAME;
Cursor cursor = database.rawQuery(query, null);
int id = 0;
if (cursor.moveToFirst())
{
do
{
id = cursor.getInt(0);
} while(cursor.moveToNext());
}
cursor.close();
return id;
}

Your delete just eliminates one row with the ID given, but that does not mean that the last row is deleted, imagine you have this table :
|---------------------|------------------|
| ID | other |
|---------------------|------------------|
| 1 | 34 |
|---------------------|------------------|
| 2 | 34 |
|---------------------|------------------|
| 3 | 34 |
|---------------------|------------------|
if you do max(id) it will return 3, if you delete the ID 2, you end up with the table like this :
|---------------------|------------------|
| ID | other |
|---------------------|------------------|
| 1 | 34 |
|---------------------|------------------|
| 3 | 34 |
|---------------------|------------------|
And your max(id) will keep returning 3 because that function just returns the higher value on the column.

The database is doing exactly what it is designed to do. It keeps the last used ID and increments it by one each time a new ID is assigned.
It does not keep a pool of the all the ID's assigned and attempt to reuse ones where the rows are deleted. That what be very complicated and slow.

Related

Is it possible to use sequence generator in this situation?

I have below table structure
ITEM
| ID(Auto Inc) | ORG_ID(FK to ORG) | ITEM_ID |
|-----------------|----------------------|-----------------------|
| 1 | 1 | 1 (Initial Val for A) |
| 1 | 2 | 1 (Initial Val for B) |
| 1 | 1 | 2 (Incremented for A) |
ORG
| ID | NAME |
|------|-----------|
| 1 | A |
| 2 | B |
Is there any possibility of using any generator to manage item_id column. This is not id column for ITEM table. Business requirement is to manage item_id sequential for each org.
You may try to insert using the next query:
INSERT INTO item (org_id, item_id)
SELECT #org_id, COALESCE((SELECT 1 + MAX(item_id)
FROM item
WHERE org_id = #org_id), 1)
where #org_id is the value to be inserted.
The problem: it may insert duplicates while concurrent insertions occures.

MySQL query to fetch list of data using logical operations

The following are the list of different kinds of books that customers read in a library. The values are stored with the power of 2 in a column called bookType.
I need to fetch list of books with the combinations of persons who read
only Novel Or only Fairytale Or only BedTime Or both Novel + Fairytale
from the database with logical operational query.
Fetch list for the following combinations :
person who reads only novel(Stored in DB as 1)
person who reads both novel and fairy tale(Stored in DB as 1+2 = 3)
person who reads all the three i.e {novel + fairy tale + bed time} (stored in DB as 1+2+4 = 7)
The count of these are stored in the database in a column called BookType(marked with red in fig.)
How can I fetch the above list using MySQL query
From the example, I need to fetch users like novel readers (1,3,5,7).
The heart of this question is conversion of decimal to binary and mysql has a function to do just - CONV(num , from_base , to_base );
In this case from_base would be 10 and to_base would be 2.
I would wrap this in a UDF
So given
MariaDB [sandbox]> select id,username
-> from users
-> where id < 8;
+----+----------+
| id | username |
+----+----------+
| 1 | John |
| 2 | Jane |
| 3 | Ali |
| 6 | Bruce |
| 7 | Martha |
+----+----------+
5 rows in set (0.00 sec)
MariaDB [sandbox]> select * from t;
+------+------------+
| id | type |
+------+------------+
| 1 | novel |
| 2 | fairy Tale |
| 3 | bedtime |
+------+------------+
3 rows in set (0.00 sec)
This UDF
drop function if exists book_type;
delimiter //
CREATE DEFINER=`root`#`localhost` FUNCTION `book_type`(
`indec` int
)
RETURNS varchar(255) CHARSET latin1
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
begin
declare tempstring varchar(100);
declare outstring varchar(100);
declare book_types varchar(100);
declare bin_position int;
declare str_length int;
declare checkit int;
set tempstring = reverse(lpad(conv(indec,10,2),4,0));
set str_length = length(tempstring);
set checkit = 0;
set bin_position = 0;
set book_types = '';
looper: while bin_position < str_length do
set bin_position = bin_position + 1;
set outstring = substr(tempstring,bin_position,1);
if outstring = 1 then
set book_types = concat(book_types,(select trim(type) from t where id = bin_position),',');
end if;
end while;
set outstring = book_types;
return outstring;
end //
delimiter ;
Results in
+----+----------+---------------------------+
| id | username | book_type(id) |
+----+----------+---------------------------+
| 1 | John | novel, |
| 2 | Jane | fairy Tale, |
| 3 | Ali | novel,fairy Tale, |
| 6 | Bruce | fairy Tale,bedtime, |
| 7 | Martha | novel,fairy Tale,bedtime, |
+----+----------+---------------------------+
5 rows in set (0.00 sec)
Note the loop in the UDF to walk through the binary string and that the position of the 1's relate to the ids in the look up table;
I leave it to you to code for errors and tidy up.

How to select next record and previous record in SQLite?

I have been searching like forever
I am using min and max for the last and and first record but how do I get the next/ record? I have a column name rowid it is the pk and auto incremented by one every time a user registers
| rowid | Name |
| 1 | John |*
| 2 | Mark |
| 3 | Peter|
| 4 | Help |
so if I click the next button I wanted to select mark which is in rowid 2
| rowid | Name |
| 1 | John |
| 2 | Mark |*
| 3 | Peter|
| 4 | Help |
but if I click the next button twice I want to be in rowid 4
| rowid | Name |
| 1 | John |
| 2 | Mark |
| 3 | Peter|
| 4 | Help |*
how do I do that? by the way I don't have fixed rows since I have a registration function
so here's my code
JButton btnNextLast = new JButton(">>");
btnNextLast.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try{
String sQuery = "select * from accountinfo where rowid = (SELECT MAX(rowid) FROM accountinfo)";
PreparedStatement prst = connection.prepareStatement(sQuery);
ResultSet rs = prst.executeQuery();
lblSID.setText(rs.getString("sid"));
lblfirst.setText(rs.getString("last"));
lblLast.setText(rs.getString("first"));
lblmiddle.setText(rs.getString("middle"));
lblbirth.setText(rs.getString("birth"));
lblcontact.setText(rs.getString("contact"));
}catch(Exception qwe){
}
}
});
I've tried
select rowid
from accountinfo
where rowid >1
order by rowid
limit 1
but no luck
and if I remove order by rowid limit 1. It just show the next record which is 2 and never function again

How to fetch next Record from the table in this case

I have a Table as shown below
+-------------+----------------------+-------------+------+------+------+
| document_id | T1 | T2 | T3 | T4 | T5 |
+-------------+----------------------+-------------+------+------+------+
| 61 | PQR | Burger | NULL | NULL | NULL |
| 66 | Chips And Chocolates | Bummy Chips | NULL | NULL | NULL |
| 69 | Test | Bummy Chips | NULL | NULL | NULL |
+-------------+----------------------+-------------+------+------+------+
I have a Pagination in my screen which got Prev and Next Buttons as shown below
On page load , i am calling a service which does this query and returns me the Result.
select * from vendor_categories ORDER BY document_id ASC Limit 1
Which fetches the First Record from the table and shows that data
My question is that on click of the Next button how can I fetch the next record (I can't rely on document_id or the data because there will be more than one user)
You can use limit and offset. You need to pass the page number as the argument.
select * from vendor_categories ORDER BY document_id ASC offset <:pageNumber> Limit 1

Delete in sqlite certain rows with specific data that are relatively old in a table using java

I want to delete for example the first 3 (oldest) that have the color1 as blue.
Example data set:
_id | name | surname | color1 | color2
1 | mark | jacobs | blue | green
2 | tony | hilo | black | red
13 | lisa | xyz | blue | green
4 | andre | qwerty | blue | green
9 | laura | abc | black | red
14 | kerr | jacobs | blue | green
I want to use execsql rather than db.delete..
which method is preferable ?
and what my code should be like ?
I will be using this inside eclipse in an android app.
db.execSQL("DELETE FROM MyTable WHERE _id IN " +
"(SELECT _id FROM MyTable WHERE color1 = ? ORDER BY _id LIMIT 3)",
new Object[] { "blue" });
execSQL is perfectly fine to use, especially when the command is so complex that using delete would require even more complex code.
It is NOT advisable to use execSql for this or any operation SELECT/INSERT/UPDATE/DELETE as execSql does not return anything, such as errors or rows affected by this query.
Instead although it takes a little longer to write out
Cursor c = db.query(table, new String[]{"_id"}, "color1" +"=?", new String[]{"blue"}, null,null,"_id ASC","3");
String ids="";
String qs = "";
for(c.moveToFirst();!c.isAfterLast();c.moveToNext()){
ids+=c.getInt(c.getColumnIndex("_id")+",";
qs+="?,"
}
ids= ids!=""?ids.substring(0, ids.length() - 1):ids;
qs= qs!=""?ids.substring(0, qs.length() - 1):qs;
db.delete(table, "_id IN ("+qs+")", ids.split(","));
Here's the reference for why execsql is bad for this situation
http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#execSQL(java.lang.String, java.lang.Object[])
DELETE FROM table WHERE _id IN
(SELECT _id FROM table ORDER BY _id ASC LIMIT 3);

Categories