Adding a record to access database from C# - c#

I have a Form Windows program in C# that adds a record to the database and can remove it.
In the database i have ID (which is Auto Number), but if i delete a record and if i want to add another record instead, the Auto Number increases and doesn't add the missing numbers.
I mean that if i have 9 records in my Access Database and i want to remove a record, it will be 8, but when i add a new record, i get 10 instead of 9. like this picture:
Is there any solution for that?

If it's an auto number, the database will generate a number greater than the last one used - this is how relational databases are supposed to work. Why would there be solution for this? Imagine deleting 5, what would you want to do then, have the auto number create the next record as 5? If you are displaying an id in your C# app - bad idea - then change this to some other value that you can control as you wish.
However what you are trying to achieve does not make sense.

if i delete a record and if i want to add another record instead, the Auto Number increases and doesn't add the missing numbers.
[...]
Is there any solution for that?
The short answer is "No". Once used, AutoNumber values are typically never re-used, even if the deleted record had the largest AutoNumber value in the table. This is due (at least in in part) to the fact that the Jet/Ace database engine has to be able to manage AutoNumber values in a multi-user environment.
(One exception to the above rule is if the Access database is compacted then the next available AutoNumber value for a table with a sequential AutoNumber field is reset to Max(current_value)+1.)
For more details on how AutoNumber fields work, see my other answer here.

In MS access, there is no any solutions for this. But in case of sql server you can create your own function rather using Identity column.

Related

Allow multiple users to update same record

I have a situation where there is one record in database table i.e. 'abcde'. And User 'X','Y' and "Z' tries to update that record at the same time.
'X' modify abcde to abcdd
'Y' modify abcde to abddd
'Z' modify abcde to abeee
All changes should persist in database table.
Is it possible than please provide the solution.
If you want to persist all changes, then you will need at least one more database table that keeps track of all these changes...a log/history table.
The question is, how do you want to handle concurrency? If you don't care about it and you only want to keep the last modification in this single record table, then you don't need any further action, except the "logging" functionality that keeps track of all changes.
But, if you do care about concurrency and want to handle it in a different then you should look at running transactions with the isolation level that best suits your needs
As you want to log the updated records only for the concurrent case . Have a column of DateTime in the table and when you display the record to keep the track of datetime. So here is the use case.
First User updated the record -> Update the original record withchange in DateTime column value also.
When Second User try to update you found that datetime has been changed , it means it is no more Update , it will be an inset statement.
It will be similar case of 2 for third user.
Now you are left with all the three records in the database.Remember in this case Primary key need to have some incremented column also otherwise it will throw an error.
You can use Trigger and save records in another Table for every operation. Capture data Change(CDC) will also work in your situation.

Reuse deleted ID field in MSSQL

Suppose I've an ID column in database:
I want to delete row number 3:
Now Id's in my database are following:
Question: Is it possible to reuse (in this case) ID 3 field. So ID 4 jumps to ID 3 field? So database should be like that:
I also know about RESEED command DBCC CHECKIDENT (MyTable, RESEED, desiredIDNumber), but I don't think that I need this in my case. Becase ALL ID's from (in my case) 2> will change. (ID3 gets ID4, and ID4 gets ID5. ID5 does not exists anymore).
Are you asking if there is a magical command to do this? Not that I have ever heard of. {Frankly I have never heard anyone even want to do this before}
Are you asking if this is technically possible? Sure. It would be a major undertaking. You could write a program that does this but the overhead of all that work to change all of the foreign key references would be pretty massive which leads to ...
Why? What are you expecting to get out of this? "Empty" space does not hurt. Did you run out of space in the integer field?
The general idea would be: UPDATE T SET ID = ID - 1 WHERE ID > 3
You can customize this to your liking. Probably you need to enable identity insert for this statement.
Be careful because this might cause corruption if other data references these IDs. IDs are generally not supposed to change. Maybe you rather add a new column ContiguousID INT NOT NULL and let the IDENTITY value alone.
If the Id column is an identity column, you cannot get Sql Server to fill in the missing IDs as part of it's automatic increment process. It won't do it.
You can fill in the ID yourself, by using the SET IDENTITY_INSERT command.
Generally, it's not worth the trouble.

Enum Vs Inner Join / Where

I have defined various text value by int. I store int value in data table for better and fast search. I have three options to display text value:
I declare Enum in my codes and display text value according to int value. It is static and I have to change code if new values is to be added.
To make it dynamic, I can store int and text value in a table which is in another database and admin own it. New values can be updated by admin in this table. I use inner join to display text value whenever a record is fetched.
I store actual text in respective data table. This will make search slow.
My question is which option is best to use under following condition?
Data table has more than records between 1 and 10 millions.
There are more than 5000 users doing fetch, search, update process on table.
Maximum text values are 12 in number and length (max) 50 char.
There are 30 data tables having above conditions and functions.
I like combination of option #2 and option #1 - to use int's but have dictionary table in another database.
Let me explain:
to store int and text in a table which is in another database;
in origin table to store int only;
do not join table from another database to get text but cache dictionary on client and resolve text from that dictionary
I would not go for option 1 for the reason given. Enums are not there as lookups. You could replace 1 with creating a dictionary but again it would need to be recompiled each time a change is made which is bad.
Storing text in a table (ie option 3) is bad if it is guaranteed to be duplicated a lot as here. This is exactly where you should use a lookup table as you suggest in number 2.
So yes, store them in a database table and administer them through that.
The joining shouldn't take long to do at all if it is just to a small table. If you are worried though an alternative might be to load the lookup table into a dictionary in the code the first time you need it and look up the values on the code from your small lookup table. I doubt you'll have problems with just doing it by the join though.
And I'd do this approach no matter what the conditions are (ie number of records, etc.). The conditions do make it more sensible though. :)
If you have literally millions of records, there's almost certainly no point in trying to spin up such a structure in server code or on the client in any form. It needs to be kept in a database, IMHO.
The query that creates the list needs to be smart enough to constrain the count of returned records to a manageable number. Perhaps partitioned views or stored procedures might help in this regard.
If this is primarily a read-only list, with updates only done in the context of management activities, it should be possible to make queries against the table very rapid with proper indexes and queries on the client side.

Insert without duplicates mysql without unique key

I have a program that is reading a credit card statement and I need it to insert it into a table. The problem i am having is when i just use insert it will let the user insert the same information over and over again. However I really cant set any of the columns as unique because there can be duplicates in all of the fields.
The fields i have are DATE | Description | Amount
So the user could have used the card on the same date at the same place and for the same amount. These are monthly statements so is there a way to do this besides insert ignore while using a unique key??
Brent
You have to clarify the business rules: Either something is required to be unique (a single column or a combination of columns) or identical lines are allowed.
If identical lines are valid, i.e. the user have used the card twice on the same date, at the same place for the same amount you cannot require the data to be unique.
What you can do is to add a warning to the user (if the data entry is interactive) if there is already an existing identical line. If you are doing some batch import you could issue a warning if all (or at least a contigous block) of transactions are identical to already existing ones.

C# WinForms - DataGridView/SQL Compact - Negative integer in primary key column

I'm just getting dirty in WinForms, and I've discovered, through a lovely tutorial, the magic of dragging a database table onto the design view of my main form. So, all is lovely, I've got my DataGridView with all of the columns represented beautifully.
BUT...
When I run my application against this brand new, empty .sdf (empty save for the two tables I've created, which are themselves empty), I get a -1 in the column corresponding to my primary key/identity column whenever I try to create that first record.
Any idea why this might be happening? If it helps, the column is an int.
#Brian -1 is a good choice for the default value since no "real" rows are likely to have identities less than zero. If it defaulted to 0 or 1 then there'd be a chance that it'd clash with an existing row, causing a primary key violation.
For applications that stay offline and create multiple rows before saving, a common practice is to continue counting backwards (-2, -3, -4) for each new row's identity. Then when they're saved, the server can replace them with the true "next" value from the table.
Since it is an Identity column and you haven't saved it to the database yet it is -1. I am assuming here that this is before you save the table back to the database, correct? You need to perform the insert before that value will be set correctly.

Categories