Allow multiple users to update same record - c#

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.

Related

Change Lookup(master) table rows to "readonly" when already in use

We have many lookup tables in the system and if it's already referred by some other tables, we shouldn't be allowed to update or delete the look-up table "value" column. eg: EnrollStatusName in below table.
Eg:
Lookup table: EnrollStatus
ID
EnrollStatusName
1
Pending
2
Approved
3
Rejected
Other table: UserRegistration
URID
EnrollStatusID(FK)
11
1
12
1
13
2
In this now I can edit Lookup table row 3 since it's not referring anywhere.
The solution which comes to my mind is to add a read-only column to look up the table and whenever there is a DML to the UserRegistration table, update the read-only column to true. Is there any other best approach to this? It can be either handling in application code or in SQL hence I'm tagging c# also to know the possibilities.
Delete is easy; just establish a foreign key relationship to some other table, and don't cascade or setnull. It's no longer possible to delete the in-use row because it has dependent rows in other tables
Update is perhaps trickier. You can use the same mechanism and I think it's neatest, instead of doing the update as an update, do it as a delete and insert - if the row is in use the foreign key will prevent the delete..
Belayer pointed out in the comments that you can use UPDATE also; you'll have to include the PK column in the list of columns you set and you can't set it to the same value it already is, nor to a value that is already in use. You'll probably need a strategy like two updates in a row if you want to have a controlled list of IDs
UPDATE EnrollStatus SET id=-id, EnrollStatusName='whatever' WHERE id=3
UPDATE EnrollStatus SET id=-id WHERE id=-3
A strategy of flipping it negative then back positive will work out only if it's not in use. If it is used then it will error out on the first statement.
If you don't care that your PKs end up a mix of positives and negatives (and you shouldn't, but people do seem to care more than they should about what values PKs have) you can forego the second update; you can always insert new values as positive incrementing and flipflop them while they're being edited before being brought into use..

getting "DateTime" of the last change in rows in a table in SQL Server?

Is there any way to find "DateTime" of the last change in rows in a table in SQL Server?
The changes (Insert / Update) are submitted by another windows application
And all I have in this table is insert_Date and there is no update_Date (and I can't add any columns or use triggers)
I've tried some queries, but all I got was the number of "User Updates" in a table, not the IDs of modified rows!
I want to get rows which are modified or inserted after a specific DateTime
If the information isn't stored in the table (or in another one by using a trigger for example) then it's impossible to track which rows were inserted after a determined datetime. You might find the time the last operation was executed at a table/index level (by querying sys.dm_db_index_usage_stats) but not at a record level.
You can't find data that doesn't exist!

How to know from client side if table was updated

I am building a C# Winforms client connected to a MySQL database. The client will be accessible from multiple users and computers. I need a way for all the clients to somehow be notified whenever another one makes a change to database contents so to refresh in the client.
Since when a user opens a form that shows database contents, the contents are fetched at runtime. So that is not the issue. If an update is made the user will see it.
My problem is if a user has a form of database content open and another user changes database content.
I thought of setting up a timer of some sort and every minute get all the database contents that the user is currently viewing. But that is very time consuming and not efficient at all.
Another thought was every minute check for updates but I do not know how to implement that.
Any suggestions?
Is there a way to get check for updates from client side?
Is there any other way to perform this?
What you could is change your table so it stores the timestamp whenever it is updated.
For example
CREATE TABLE foo (
id INT PRIMARY KEY
x INT,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP,
KEY (updated_at)
);
The above code store the current timestamp to a new row and changes it the time edited whenever a row is edited. This way you can get the data, sort it (order by) in descending mode and get the top record. That way you get the last updated record in your table.
If you want to know for the whole database then you have to compare the last updated record for each of your tables and get the most recent one.

Adding a record to access database from 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.

Best way to check whether a row has been updated in SQL

I have an update statement which updates a table. And there is a column that records the last modified time. If data in a specific row has not been changed, I don't want to change the last modified date time.
What is the best way to check whether an update statement will change the row of data or not.
Thanks,
Check the old vs. new data in your code instead of doing it in a query.
No need to bother the DB layer unnecessarily if data didn't change at all.
In short, if data didn't change, don't send the UPDATE statement.
One way is to start a transaction, select the contents of the row and compare it to what you're going to update it to. If they don't match, then do the update and end the transaction. If they match, rollback the transaction.
Sounds like you are going through a table and modifying some rows, then you want to go BACK through the table a second time and update the timestamp for the rows that were just changed.
Don't do it in two passes. Just update the date/time at the same time as you update whatever other columns you are changing:
UPDATE myTable
SET retailprice = wholesaleprice * 1.10,
lastmodified = GetDate()
WHERE ...
Or are you issuing an update statement on ALL rows, but for most rows, it just sets it to the value it already has? Don't do that. Exclude those rows that wouldn't be modified in your where clause:
UPDATE myTable
SET retailprice = wholesaleprice * 1.10,
lastmodified = GetDate()
WHERE retailprice <> wholesaleprice * 1.10
If you want to do this preemptively, the only way I can think of that you will do this is to modify the WHERE clause of the update statement to compare the existing value vs the new value (for EVERY value). If ANY of them are not equal, then the update should take place.
That's when a DAL is handy. It keeps track of all colums so if none changed then I don't even send an UPDATE statement to the database.
It depends on whether you have control of the data or not. Seb above is correct in saying you should check the old data against the new data before doing the update. But what if the data is not under your control?
Say you are a webservice being asked to do an update. Then the only way to check would be to query the existing data and compare it to the new data.
Don't know of any SQL functionality that would detect whether the update has actually changed any data or not.
There are ways in SQL to detect how many rows have been included in an update statement. Don't know of a way to detect whether an update statement actually changed any data, that would be interesting to know.
If you are using sql 2005/2008 then you can do as follows in the stored procedure.
update newTable
set readKey='1'
output inserted.id,
inserted.readKey as readKey,
deleted.readKey as prevReadKey
into #tempTable
where id = '1111'
Then you can select from #tempTable to verify if the prevReadKey and readKey has similar value if both has similar value you can reset your last modified datetime.
This way you don't have to fire multiple queries on the table in the case when a value is actually changing. But yes in the case when the value is not changing, this will be firing two update statements where none is required. This should be OK if those cases are rare.
P.S. NOTE:- The query given might be syntactically wrong as it is not tested. But this is the way your problem can be solved. I have done it in following way using OUTPUT clause with Merge statement in one of my project and it can be done with update statement too. Here is the reference of OUTPUT Clause
You COULD write an INSTEAD OF UPDATE trigger in T-SQL, where you could do what has been suggested above in the DAL layer -- compare the values in the existing record vs. the values in the update statement and either apply the update or not. You could use the Columns_Updated() function in the trigger to see if anything had been updated, and proceed accordingly.
It's not particularly efficient from the machine's point of view, but you could write it once and it would handle this situation no matter which application, stored procedure or other process was trying to update the record.

Categories