First of all I am using SQLite-Net-Pcl on Xamarin.Android
My question is this, I need to create an event that is recursive,
and I need to connect all those recursive events (in case of someone edditing them or delleting them).
And I need to use the original Event's Id to connect it to the others
-> creates new recursive event
-> gets the id of inserted event
-> uses that id to connect all recursive events together on a "NumDocConnection"
My Id is auto-incremented, and is the primary key.
So, how can I get the id of the last inserted event? or is this even a good way do to deal with the situation?
how can I get the id of the last inserted event?
The int-based primary/auto-inc value is obtained via the object that you inserted (the object instance is updated during the Insert with the new value).
var newRecord = new Record { SomeString = "StackOverflow" };
var numofRecordsInserted = conn.Insert(newRecord);
Console.WriteLine($"Newly inserted id = {newRecord.Key}");
is this even a good way do to deal with the situation
That depends upon your application. A pri-key/auto-inc field does prevent the reuse of the generated IDs, that is until the database is reset (via deletion/re-creation or a reset via the the sqlite_sequence table).
Should you use it as a "foreign" key, lots of opinions here, some yes, some no.... Personally if you never use it externally to your app (i.e. it is not transmitted/sync'd via a remote API) it works well/fast as a foreign key if you understand how SQLite creates it and when it can/could be reset, see the linked docs.
If the AUTOINCREMENT keyword appears after INTEGER PRIMARY KEY, that changes the automatic ROWID assignment algorithm to prevent the reuse of ROWIDs over the lifetime of the database. In other words, the purpose of AUTOINCREMENT is to prevent the reuse of ROWIDs from previously deleted rows.
re: https://sqlite.org/autoinc.html
Related
I'm building an app for Android where I'm reading the instances table to get all events.
I've used the "unique" row id as a way to reference to different instances, however I've now found that the row id changes over time, it actually seems to increment by 2 every now and then. Is there a reason for this behaviour? What is the recommended way to handle instances and how to uniquely reference each instance?
This is the only code I use when creating the meeting objects in the app.
int columnID = cursor.getColumnIndex(CalendarContract.Instances._ID);
String uniqueid = cursor.getString(columnID);
meeting.setUniqueId(uniqueid);
I think you should be using CalendarContract.Instances.EVENT_ID instead as the documentation describes that as the unique ID for events: EVENT_ID
_ID might be changing because they are adding/removing rows under the hood without caring for the changes.
i am really stuck at this point of my android app development.
What i need is a way to save a changing amount of int or string-values (in a sql database). Yet im not even sure if this is the right approach, but let me explain:
In the app i am currently working on, you are able to create certain "events". Users should be able to apply for such events.
I have an external database with 2 tables:
first one for users - every user has a unique ID
second one for events - every event has a unique ID
I need each event to know what users applied for it. And i need each user to know what events they applied for.
I was thinking to save the Event-IDs in the User-Table and vice versa.
I just dont know how to do that since the amount of applicants/ID's can change. Is there a way to save Arrays in the database which can easily be edited (e.g. +/- one ID) and read?
Is this even the right way? I am very happy for any advise!
Thanks in advance!
What you seem to want is a many-to-many relationship. A user can be part of many events, and an event can have many users. That requires an additional table though:
Table: User Columns: UserId, Name, ...
Table: Event Columns: EventId, Name, ...
Table: UserEvents Columns: UserId, EventId, ...
In the new table, UserEvents, you would store the UserId's and EventId's like this:
UserEvents
UserId EventId
1 1
2 1
1 2
This means that if you selected UserId 1, the query would return EventId 1 & 2. If you selected EventId 1 the query would return that UserId 1 & 2 would be attending.
This is the standard and recommended way to deal with many-to-many. It's very flexible and can easily be scaled.
You could either use a Compound key (Composite Key) for this table, or create a column specifically as a Primary Key. The code below can be used, and manipulated, to create both your table and Compound/Composite key (I'm guessing on data types).
CREATE TABLE UserEvents
(
[UserId] INT NOT NULL,
[EventId] INT NOT NULL
CONSTRAINT PK_UserEvents PRIMARY KEY NONCLUSTERED ([UserId], [EventId])
)
I would add a third table (e.g. UserEvents) to store which events a user has applied for, along with other relevant attributes (e.g. ApplicationTime, ApplicationStatus). This association would have a foreign key relationship back to the related tables and resolve the many-to-many relationship between users and events.
What you have there is called a "many-to-many" relationship between to tables which can only be resolved by the introduction of a third table between your two tables that stores the associations.
This table would contain the User-ID and the Event-ID as foreign keys (and maybe additional information).
In my database I have three tables (A,B,C) in which table A has foreign keys into both B and C. When I delete from either B or C, I want to also delete the row in A if BOTH foreign keys are null, and I have a constraint placed on the foreign keys that sets them to null if the B or C table deletes that key. I have two triggers on tables B and C to delete a row from A when appropriate and this seems to be working okay.
The trouble I'm having is there is a file name stored in table A that I want to delete but I can't if I set up triggers to handle my situation. So is there any way to know when a trigger is fired? Do I have to manually execute the logic for my trigger so I can delete the file too?
tl;dr: How can I execute some java code when a trigger is fired in my applications sqlite database?
SQLite itself has user-defined functions, but the Android database API does not allow you to access them.
You have to do the checks in your code whenever you have issued such a DELETE statement.
Best way to do this I found is to return the rowID.
long newRowId;
newRowId = db.insert(tableName,primaryKey,values); (insert or delete or whatever)
If that trigger fires you will get a row id of -1. Then just show your message or run your query where you delete something else when you get a row id of -1
I am fetching my data with id which is Integer primary key or integer.
But after deleting any row...
After that if we make select query to show all.
But it will give force close because one id is missing.
I want that id can itself take auto increment & decrement.
when i delete a record at the end(i.g. id=7) after this i add a row then id must be 7 not 8. as same when i delete a row in middle(i.g. id=3) then all the row auto specify by acceding.
your idea can help me.
Most systems with auto-incrementing columns keep track of the last value inserted (or the next one to be inserted) and do not ever reissue a number (give the same number twice), even if the last number issued has been removed from the table.
Judging from what you are asking, SQLite is another such system.
If there is any concurrency in the system, then this is risky, but for a single-user, single-app-at-a-time system, you might get away with:
SELECT MAX(id_column) + 1 FROM YourTable
to find the next available value. Depending on how SQLite behaves, you might be able to embed that in the VALUES list of an INSERT statement:
INSERT INTO YourTable(id_column, ...)
VALUES((SELECT MAX(id_column) + 1 FROM YourTable), ...);
That may not work; you may have to do this as two operations. Note that if there is any concurrency, the two statement form is a bad ideaTM. The primary key unique constraint normally prevents disaster, but one of two concurrent statements fails because it tries to insert a value that the other just inserted - so it has to retry and hope for the best. Clearly, a cell phone has less concurrency than, say, a web server so the problem is correspondingly less severe. But be careful.
On the whole, though, it is best to let gaps appear in the sequence without worrying about it. It is usually not necessary to worry about them. If you must worry about gaps, don't let people make them in the first place. Or move an existing row to fill in the gap when you do a delete that creates one. That still leaves deletes at the end creating gaps when new rows are added, which is why it is best to get over the "it must be a contiguous sequence of numbers" mentality. Auto-increment guarantees uniqueness; it does not guarantee contiguity.
I want to generate automatic id of type ame100, ame101 and so on, so that as soon as I start my Android application, the next value of the series ame*** which is currently not in the database, should come automatically in edittext. So that on submitting the form I should have that value in database.
Make your primary key autoincrement, so that db will generate the next value.
Each time you need new id, just ask your databse for MAX(ID) from your table.
Increment it and set to edittext!
Note: this solution works only if you have one place of inserting the values.
I would suggest not showing the number before inserting, but create it after, when you already have generated id of the object.