Primarily, sorry for being too descriptive.
I am storing patient's info in sql db by creating a custom ID field "PatientID" and I have a primary key field "ID". PatientID has a pattern "PID-1" or "PID-2" so on and so forth. I want to synchronize both IDs. Like if table's ID for "John" is 4 then its patientID should also be "PID-4". For this, I have done some coding like if no record exist then start saving patientID from "PID-1" and then for all next record first find the max id of patient from ID field and increment it by 1 and concatenate it with "PID" + (tableID+1).
ID PatientID
1 PID-1
2 PID-2
3 PID-3
4 PID-4
Now, for an instance, while adding more record an exception is thrown although record is not saved but ID gets incremented. And here comes the problem. Suppose, some bug comes and record for ID 5 could not be saved in the db, after fixing that bug when program runs correctly it put the ID 6 rather than 5. And for the patientID it puts "PID-5" due to MAX query. From here both IDs start being distinct. Same problem for deleting, if I am deleting last record from above table i.e, 4 and PID-4, the next record's ID would be 5 while PatientID would be "PID-4". This was the whole problematic picture of handling both IDs from my side. Any alternate solution or any modification in my idea or any better idea then mine would be highly appreciated.
In SQL Server you could create a computed column for this purpose:
ALTER TABLE Patient DROP COLUMN PatientID;
GO
ALTER TABLE Patient ADD COLUMN PatientID AS ('PID-'+CAST(ID AS VARCHAR(15));
For more info regarding computed columns, please have a look here.
Note: I assumed that your table's name is Patient. You have to change this correspondingly if this is not the name of your table.
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
Sorry not good in english, hope you all can understand and please help.
I have unique identity for each item.
In the program, it can only have 200 itemsID
For instance, when the user create the first item, the database will assign itemID 1 to the first item, itemID 2 to second item till itemID 200.
User can delete the items. For instance, user delete from itemID 1 to itemID 20. So when user create a new item, i want to reuse the itemID 1, may i know how can i do about it?
For fresh start, whenever user create new item, i will check database for the max item id then retrieve it and add 1.
mySql_ = "SELECT MAX(ITEM_ID) FROM ITEM";
Object returnValue = ExecuteSql(mySql_);
if (DBNull.Value.Equals(returnValue))
{
ItemId += 1;
}
My table design structure is as follow
CREATE TABLE ITEM (
ID NOT NULL PRIMARY KEY
ITEMID NOT NULL
ITEM_NAME
)
The above will be my table structure. I only allowed to have maximum itemID of 200. For example, user have created 200 items (table will have itemID 1 to 200), So if user want to create more items, they delete from itemID 1 to itemID20. So the next time when user create item, the new item insert to table will be itemID1.
If you are using SQl server and Identity. Identity fields do not reuse old values by default. You can reseed them with DBCC CHECKIDENT (orders, RESEED, 9)
That means you'll have to run the statement based on every DELETE.
It is generally not a good idea to handle IDs yourself. Let SQL Server do this withan identity column. You especially shouldn't reuse IDs after delete if your ID is the orimary key. That will degrade insert and index performance. It is always most efficient to add primary key values at the end of the range.
Especially to query your MAX(ID) is not efficient. If you want to reuse IDs without compromising good DB design, you can create a table that contains your ID pool and link with a foreign key:
CREATE TABLE IDPool (
ID TINYINT NOT NULL PRIMARY KEY
--More columns if you need them
)
This table contains one entry for each reusable ID, so in your case 200 entries with ID 1 to 200
Your item would look somehow like this:
CREATE TABLE Items (
ID INT NOT NULL IDENTITY PRIMARY KEY,
PooledID TINYINT NOT NULL FOREIGN KEY REFERENCES IDPool(ID)
--Your other columns
)
You can insert new items like this:
INSERT INTO Items (PooledID)
VALUES ((SELECT MIN(ID) FROM IDPool p WHERE NOT EXISTS (
SELECT * FROM Items i WHERE p.PooledID = i.ID
)))
I don't think that your approach is good. You should use identity field which is always unique and don't use old id's anyway. But if you really want to use your approach try to create one more attribute in database. Let's say Hidden field.
When user delete record in application you just update this row and set it as Hidden (Hidden=1).
When user create new record you again update this record and set it to visible (Hidden=0).
The you can build application based on this filed and you can show/hide/work with records in base of Hidden attribute.
I need a way to generate ids for a database based on certain information. Depending on the conference the user is registering for, the id will differ. The id will be 4 digits of the event identifier concatenated with 5 sequential digits. For example:
Event A: 1000
Event B: 2000
Event C: 3000
An id for event A could be 100012345, and the next number for this id would be 100012346. An id for event B could be 200012345. Etc.
So how can I grab the last id for a certain event?
How can I autogenerate the next number for this?
Use uniqueidentifier type for IDs with newid() default value , not int. This will create automatically new id of type guid.
If the problem is to take last created ID.Create two new columns in your table UpdateDate and CreateDate. When you are inserting a record
CreateDate = DateTime.Now;
On update
UpdateDate = DateTime.Now;
If you want to take last create item you will fetch data from database with this query:
Select * from [TableName] Order By CreateDate Desc
I suggest you split the event and id as two separate columns in the DB and make them both primary key.
Then, should you need to add another key, first check what event you need (for example 1000) then check on DB what's the max id for that event. This should answer your first question.
As for your second question, once you have the max id for the event, you can just add +1.
Or even better, you could define id as auto-increment, but I'm not sure it'll work on a single part of a complex primary key.
Hope this helps! :)
If you insist on combining the two int values as a string then you would have to search. Since you are using strings you will need to make sure your sequence number is zero padded e.g 200000001 being the first id for event B. Given this then the query
Select top 1 ID from [TableName] Where ID like '2000%' Order By ID Desc
should get you the largest ID and you will have to break it apart/convert to int and increment it. Of course you will then need some collision handling code when you attempt to create the record unless you are single thread/process when changing the db.
You might want to consider breaking these two concepts apart. You could use individual int fields to prevent doing string searches and instead combine the two int values when you need to present them as a combined identifier. Then you r SQL is
Select Top 1 SequenceId from [TableName] Where EventId=2000 Order By SequenceId Desc
Also if you truly want auto incremented sequence identifiers then you would have to move to a table per event with an auto incremented PK on each table as primary keys are the only auto incremented fields in SQL Server.
In my opinion, a trigger would be a good bet. You could create an sql trigger which would fire before the insert, checking which event the user is registering for, and generating the corresponding Id.
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.
I'm putting data from website (json) to sql base.
In db i have these rows.
ID | PostId | Name | Message
Id is auto-increment primary key.
PostId also has a unique values.
Name and Message are nothing special.
When I run my script / click on the button in form / ... , the program saves all the values into database (lets say there are 25).
Next time I'm going to press the button there will be added 25 more records (all duplicates), and so on...
Is there a way that the program can check through 'PostIds' if the value already exists before adding it to the db?
Thanks
Another way is to use merge statement, this can also update the duplicate rows if you like and is easier than useing an if statement
if not exists(select * from table where PostId =#PostId)
Begin
//add
End
You have many option
Simple one is that you ask Your data base about that PostId
SELECT count(PostId) FROM Table where PostId = #PostId;