I have created a multi-tenant application in which users creates record which has an unique number like a primary key. Every record that is added to the system increases that unique number and labels itself with that number.
My problem is, when two users try to insert a record at the same time, I get the same unique number. I want that number to be unique.
I tried to work with threads, assumed the second thread will wait for the first one to get the correct number and continue. But it didn't go as I planned.
I have also tried table triggers. When a new record inserted, I just updated the field with the latest unique ID. But still when two record comes at the same time, got same unique ID.
I expect to create unique id column, like a primary key. I understand that it could be done with in database or code.
Related
i have a datagridview connected to my sql database . it looks like this
create table Scule
(
id int Identity constraint pk_idscule Primary key,
unelte varchar(255),
nume_persoana varchar (255),
data_luat date,
data_adus date
);
Whenever I add something in the datagridview my id is getting incremented but only visually with values starting from -1 going down..in the database it is getting saved well tho. i`m using windows forms c#. if i switch between the last two rows it will just increment it lower and lower for no reason. I've tried to remove the identity and constraint from id in sql but no result
Yes, that's how it works. I suspect you have a datatable as the backing for your grid, the primary key column is specified as being autoincrement with a negative step (the typical behavior when you create a DataSet and fill it with DataTables and TableAdapters)
It is important to remember that a DataSet is nothing at all to do with the database; it is a local set of containers in which data is held while you show it on a form and work with it. Adapters load it down from and save it up to a database
This auto negative number is a mechanism that allows you to have data in the local DataSet that satisfies the "a primary key as a number" constraint and also allows you to keep data together in a related way. So you've got a Scule- I'll pretend that's a School, where people learn stuff. A School has students so you'll probably have another table Students. Every Student has a SchoolId that associates them to a School. This means you can have a relationship between a school and Student
When you add a new School it gets an Id of -1. If you added 10 students they would have IDs between -1 down to -10, and their SchoolId would be -1
When you save the school to the db (and you need to save the school first so there is something the associate the students to) the DB will generate an actual school of, like 427
By magic (actually by running SELECT SCOPE_IDENTITY() after the insert that creates the school in the DB) the DataSet will download the real value of 427 and replace the -1 with it. If you have it configured to cascade this update (you should) then all the related students (those who have a school ID of -1 before the save) will also have their school if updated to 427. This way the data remains associated together:
school ID is -1
ten students have SchoolId -1
school is saved and gets 427 in the dB
school object in the DataSet gets 427
student objects update to 427
The students can now all be saved to the db and they will be associated with the school 427
Mostly you should ignore this -1 value - you're only bothered about it because you can see it but generally we don't show the primary key to the user. You find the ID keeps decreasing when you go between the last row and the second to last because going into the last row makes a new temporary scule, but you then never fill it out so it's never committed. To prevent problems the temporary of is never reused so the negative increment keeps happening. Don't worry about it, it's absolutely unimportant in the grand scheme of things. The best thing you could do for yourself and your user sis remove the PK column from the grid so you can't see this happening
With LINQ, I'm trying to delete a selected row in datagrid from database (made with code first) using db.Dishes.Remove(Dish);
But when I delete the item and inserting a new one, primary key (id) of new item "jumps" a value.
E.g.
1 Shoes
2 Jeans //I delete this item
When adding a new Item
1 Shoes
3 T-Shirt //jumps a value for Id
I've tried with this too in my DBContext.cs
modelBuilder.Entity<Cart>()
.HasOptional(i => i.Item)
.WithMany()
.WillCascadeOnDelete(true);
But it's not working
Is there a better way to delete an item from database?
The thing is that when we use DELETE it removes the row from the table but the counter is not changed (if the deleted row has an auto increment PK) see DELETE vs TRUNCATE
.
So, if you want to reuse the key value then you could do something on the lines of:
1) Handle the Auto Increment part of Key in your code
2) If you have
access to DB or want to query it something on the lines of this will
might be of help (SQL Server) :
DBCC CHECKIDENT ('tablename', RESEED, newseed)
to do this from code you could after the delete do :
db.ExecuteCommand("DBCC CHECKIDENT('tablename', RESEED, newseed);")
where 'newseed' is the id of the deleted row.e.g if newseed is 0 then next insert will be 1 and if it is 10 then the insert will have 11. To get the new seed value you could also get the max id value residing in your db and then work from there. Better check out what approaches you can take if you decide to go down that road.
From Reset autoicrement in SQL Server and how to use it in code.
If your primary key is an auto integer, you cannot avoid this behavior. This is simply how the database works. If you want to control the int value, do NOT make it the primary key and do not use auto integer. Instead use uniqueidentifier as your primary key and make your int a normal field. Then when you create your new records, you need to have a robust mechanism to get the next index, lock it so nobody else can steal it, and then write your record.
This is not trivial in a multi-threaded environment! You should do some research on the topic and come up with a good scheme. Personally, I'd NEVER attempt to do this and would use a repeatable process to generate numbers that are non-sequential or unique to a thread.
The primary key has to be unique (by definition), and you have also defined it as an identity column.
So when you delete a row and create a new one, that new one will take the next available key (3 in your case).
If you don't want this behaviour you will have to manage the uniqueness of the primary key yourself.
C# interface accessing Sql server db.
I have a table with a composite key ID and revision.
When I "insert" a new record I want to auto increment the ID.
When I "update" the record I want to actually insert a new record but increment revision.
What is the proper table settings for this?
What I have done in the past is actually use a trigger for UPDATE. It would copy all the values into a new record and increment the version column. I would also have an indexed column that would serve as a key, but not a primary key so that all revisions would be tied together.
I have a SQL table that stores different data. And the primary key has integer value that is incremented 1 one new data is entered. As long as we keep on adding it works fine. But when we delete any center value or ending value it causes problems.
i.e for example I have added 5 rows in the table. And the column sr_num holds value of 5. And when I delete the 4th record the sr_num column remains like this: 1,2,3,5.
I want it to be 1,2,3,4 as soon as I delete the 4th entry, I want the 5th one to take 4th position and same number as well.
It must to happen to all.
No. That is not what your primary key is used for. It is only for logical reference, to allow for uniqueness. You should mentally ignore the fact that it uses an integer. #Adriano and #marc_s are both correct. Let go of the idea that you could/should renumber your primary key values. There are some rare occasions when you might consider it, but this is not one of those rare occasions.
Instead, you could set up a query (or view) that uses ROW_NUMBER() in your query (as #Adriano mentioned). Then, you will have your consecutive numbers without messing with your primary key values. People usually refer to this as an ordinal column or simply Ord.
It is a bad Idea what you want to.
example: your sr_num has a foreign key to other table, once you
update the sr_num you need to update the other table with the same
value as sr_num too.
I am creating application that uses MYSQL database in C#. I want to delete row and update autoincremented value of id in table. For example, I have table with two columns: id and station, and table is station list. Something like this
id station
1 pt1
2 pt2
3 pt3
If i delete second row, after deleting the table looks something like this:
id station
1 pt1
3 pt3
Is there any way that I update id of table, for this example that id in third row instead value 3 have value 2?
Thanks in advance!
An autoincrement column, by definition, should not be changed manually.
What happen if some other tables use this ID (3) as foreign key to refer to that record in this table? That table should be changed accordingly.
(Think about it, in your example is simple, but what happen if you delete ID = 2 in a table where the max(ID) is 100000? How many updates in the main table and in the referring tables?)
And in the end there is no real problem if you have gaps in your numbering.
I suggest you don't do anything special when a row is deleted. Yes you will have gaps in the ids, but why do you care? It is just an id.
If you change the value of id_station, you would also need to update the value in all tables that have an id_station field. It causes more unnecessary UPDATES.
The only way to change the value of the id column in other rows is with an UPDATE statement. There is no builtin mechanism to accomplish what you want.
I concur with the other answers here; normally, we do not change the value of an id column in other rows when a row is deleted. Normally, that id column is a primary key, and ideally, that primary key value is immutable (it is assigned once and it doesn't change.) If it does change, then any references to it will also need to change. (The ON UPDATE CASCADE for a foreign key will propagate the change to a child table, for storage engines like InnoDB that support foreign keys, but not with MyISAM.
Basically, changing an id value causes way more problems than it solves.
There is no "automatic" mechanism that changes the value of a column in other rows when a row is deleted.
With that said, there are times in the development cycle where I have had "static" data, and I wanted control over the id values, and I have made changes to id values. But this
is an administrative exercise, not a function performed by an application.