Check for previous and next entry in SQLITE - java

I have an android application that uses a sqlite database. My app has a next and previous button to view entries in the database. I need to check whether or not a next or previous entry exists that way i can disable the button if one does not exist.

Run a query to get the IDs of each record in the table and cache this. Then you know if there are next or previous entries. Click the button, and your app would do a primary key lookup based on the cached data.

Try something like this:
SELECT *,
(SELECT id FROM my_table WHERE id < <my_id> ORDER BY id DESC LIMIT 1) AS previous_id,
(SELECT id FROM my_table WHERE id > <my_id> ORDER BY id ASC LIMIT 1) AS next_id
FROM my_table WHERE a = <my_id>

Related

I need to update the id along with the name and desc - SQL

I am selecting the id using
SELECT SCRTY_RISK_AREA_UI_AREA_ID_SQ.nextval as\"riskAreaNo\" FROM DUAL
This sql query from the database.
Now I need to update the name and description of the already existing data along with the id
UPDATE SCRTY_RISK_AREA
SET AREA_NAME= :areaName, AREA_DESC= :areaDesc,IS_ACTIVE='N'
WHERE UI_AREA_ID = :uiareaId");
Am updating using the above query.
Can anybody help me how to insert or generate the new id. am new to sql not sure how to generate new id
I am not sure how to update along with the id since i generate the id using sequence
If you're inserting a new row, then
insert into scrty_risk_area (id, area_name) values
(scrty_risk_area_ui_area_id_sq.nextval, :areaName);
If you're updating existing ID values (probably not a good idea, especially if it is a primary key, not to mention if it is referenced by some foreign keys):
update scrty_risk_area set
id = scrty_risk_area_ui_area_id_sq.nextval;

SQLite Java: update table ID's after deleting item automatically

i'm using SQLite to store data and if i delete the last row, ID is 4 and after that add a new row and the ID is 5 and it should be 4. And when trying to view the data it crashes since it can't find data from ID 5.
Database Inspector
In database inspector left of the ID column is a row number. is this accessible since that would solve the problem or is it just a row number indicator in Android studio.
Thank you and have a nice day!
Got it working by adding these:
String strSQL1 = "UPDATE people_table SET id = (id +1) WHERE id < 1";
String strSQL = "UPDATE people_table SET id = (id -1) WHERE id > 1";
db.execSQL(strSQL);
db.execSQL(strSQL1);
The id goes right one even if I delete something between first and last one.
And you need to remove autoincrement from id for this to work.
I think you can use a method to recover the last item that you insert, or the one with the higher id, with that you have the value of the next id that you need to put as an extra. If you need it when there are no values then save it when you delete the last item, or reset the data base so that ir reestart the count of the id

How can I access a value when inserting into a table?

I'm trying to write a java sql query, the simplified table would be table(name,version) with a unique constraint on (name, version).
I'm trying to insert a row into my database with a conditional statement. Meaning that when a entry with the same name exists, it should insert the row with same name and its version increased by 1.
I have tried with the following:
INSERT INTO table(name,version)
VALUES(?, CASE WHEN EXISTS(SELECT name from table where name=?)
THEN (SELECT MAX(version) FROM table WHERE name = ?) +1
ELSE 1 END)
values are sent by user.
My question is, how can I access the 'name' inside the values so I could compare them?
If you want to write this as a single query:
INSERT INTO table (name, version)
SELECT ?, COLAESCE(MAX(t2.version) + 1, 1)
FROM table t2
WHERE t2.name = ?;
That said, this is dangerous. Two threads could execute this query "at the same time" and possibly create the same version number. You can prevent this from happening by adding a unique index/constraint on (name, version).
With the unique index/constraint, one of the updates will fail if there is a conflict.
I see at least two approaches:
1. For each pair of name and version you first query the max version:
SELECT MAX(VERSION) as MAX FROM <table> WHERE NAME = <name>
And then you insert the result + 1 with a corresponding insert query:
INSERT INTO <table>(NAME,VERSION) VALUES (<name>,result+1)
This approach is very straight-forward, easy-to-read and implement, however, not really performant because of so many queries necessary.
You can achieve that with sql alone with sql analytics and window functions, e.g.:
SELECT NAME, ROW_NUMBER() over (partition BY NAME ORDER BY NAME) as VERSION FROM<table>
You can then save the result of this query as a table using CREATE TABLE as SELECT...
(The assumption here is that the first version is 1, if it is not the case, then one could slightly rework the query). This solution would be very performant even for large datasets.
You should get the name before insertion. In your case, if something went wrong then how would you know about it so you get the name before insert query.
Not sure but you try this:
declare int version;
if exists(SELECT name from table where name=?)
then
version = SELECT MAX(version) FROM table WHERE name = ?
version += 1
else
version = 1
end
Regards.
This is actually a bad plan, you might be changing what the user's specified data. That is likely to not be what is desired, maybe they're not trying to create a new version but just unaware that the one wanted already exists. But, you can create a function, which your java calls, not only inserts the requested version or max+1 if the requested version already exists. Moreover it returns the actual values inserted.
-- create table
create table nv( name text
, version integer
, constraint nv_uk unique (name, version)
);
-- function to create version or 1+max if requested exists
create or replace function new_version
( name_in text
, version_in integer
)
returns record
language plpgsql strict
as $$
declare
violated_constraint text;
return_name_version record;
begin
insert into nv(name,version)
values (name_in,version_in)
returning (name, version) into return_name_version;
return return_name_version;
exception
when unique_violation
then
GET STACKED DIAGNOSTICS violated_constraint = CONSTRAINT_NAME;
if violated_constraint like '%nv\_uk%'
then
insert into nv(name,version)
select name_in, 1+max(version)
from nv
where name = name_in
group by name_in
returning (name, version) into return_name_version;
return return_name_version;
end if;
end;
$$;
-- create some data
insert into nv(name,version)
select 'n1', gn
from generate_series( 1,3) gn ;
-- test insert existing
select new_version('n2',1);
select new_version('n1',1);
select *
from nv
order by name, version;

Mysql Duplicate entry 'xxxxxxxx' for key(unique) 'xxxxxxxxxx'

I have a problem of updating a row. I have a column called serialNum with varchar(50) not null unique default null
When I get the response data from the partner company, i will update the row according to the unique serial_num (our company's serial num).
Sometimes update failed because of :
Duplicate entry 'xxxxxxxx' for key 'serialNum'
But the value to update is not exists when i search the whole table. It happens sometimes, not always, like about 10 times out of 300.
Why does this happen and how can I solve it?
below is the query i use to update:
String updateQuery = "update phone set serialNum=?, Order_state=?, Balance=? where Serial_num=" + resultSet.get("jno_cli");
PreparedStatement presta = con.prepareStatement(updateQuery);
presta.setString(1, resultSet.get("oid_goodsorder"));
presta.setString(2, "order success");
presta.setFloat(3, Float.valueOf(resultSet.get("leftmoney")));
presta.executeUpdate();
I think the reason is in resultSet.get("oid_goodsorder") where did you get this result? is 'oid_goodsorder' is unique? Did you always updates whole table?
If oid_goodsorder is unique, it is possible to have duplicates in serialNum, because you don't use bulk update, instead you update every record separately, therefore it is possible:
Before:
serialNum=11,22,33,44
oid_goodsorder=44,11,22,33
It tries to update first serialNum to 44, but 44 is exists!
But if you finish all update serialNum will be unique...
If you wants to get error rows you could disable set serialNum is not unique and check table for duplicating serialNum
If you don't have duplicating values try to use bulk update
Java - how to batch database inserts and updates

Insert only if row doesn't exist

I am using PreparedStatement to prepare sql queries. I want to insert a row in table if and only if it doesn't exist.
I tried this -
INSERT INTO users (userId) VALUES (?) ON DUPLICATE KEY UPDATE userId = ?
But this will unnecessarily update the userId.
How can i insert the userId here ?
INSERT INTO users
(userId)
SELECT ?
WHERE NOT EXISTS
(
SELECT *
FROM users
where userId = ?
)
You may use
INSERT IGNORE INTO users (userId) VALUES (?)
But you should understand why do you want ignore errors.
on duplicate key does not work correctly when the table is an innodb. It creates exactly the problem you are describing. If you need the functionality of an innodb, then should you first check the existence of the row, otherwise can you convert the table to a myisam table.
edit: if you need to check the existence of the row before the decision to insert or update, then would I advice you to use a stored procedure.
DELIMITER //
CREATE PROCEDURE adjustusers(IN pId int)
BEGIN
DECLARE userid int;
select count(id) into userid from users where id = pId;
if userid = 1 then
update users set id = pId where id = pId;
else
insert into users(id) values(pId);
end if;
END //
DELIMITER ;
A stored procedure is precompiled, just as a prepared statement. Hence no SQL injection problems and some more functionality and only one call to the database.

Categories