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.
Related
I want to monitor insertions in an SQL Server table. Like two columns UserID and Activity from a table (userData) so that as soon as the insertion happens to this table, I get the values that were inserted and passed to C#.
I want to use each insertion for comparison like comparing each insertion with some value and take actions upon them.
PS. I know how to get data from SQL Server and insert data to SQL Server table using C#. But don't know how to achieve it on a real-time basis to take decisions upon them.
You can use SqlDependency class and use it's OnChange event. Go through the linked MSDN document to see an example on how.
dependency.OnChange+=new
OnChangeEventHandler(OnDependencyChange);
Create an Insert Trigger
CREATE TRIGGER [dbo].[userDataInsert]
ON [dbo].[userData]
FOR INSERT
AS
BEGIN
SET NOCOUNT ON
select *
from inserted
-- do whatever you need with inserted
END
Use can also look at SqlTableDependency. It is a c# component raising events when a record is changes. You can find more detail at: https://github.com/christiandelbianco/monitor-table-change-with-sqltabledependency
SqlTableDependency is a high-level C# component used to audit, monitor and receive notifications on SQL Server's record table changes. For any record table change, as insert, update or delete operation, a notification containing values for the record changed is delivered to SqlTableDependency. This notification contains insert, update or delete record values.
This table record tracking change system has the advantage to avoid a select to retrieve updated table record, because the updated table values record is delivered by notification.
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!
I have a table controller, which has one way sync (Only get since there is no any update from mobile). So the very first time when I do the PullAsync it has pulled whole data since my Update At filed has the same timestamp for all the records. Now Second time I just wanted to do the incremental Pull (Note I do pass a name value to PullAsync to enable incremental sync).
But the problem is, it retrieves whole data again since there is no updated time stamp in Updated At (Because there is no update method in the Table Controller since it is one-way sync-Azure to mobile). How can I omit pulling data again if there is no update while all the Update At values are same time stamp? The issue is same as mentioned in below link. Do we still need to do one record update in order to fix this?
https://social.msdn.microsoft.com/Forums/office/en-US/ff002e85-1313-449f-89eb-cd45c1a4846c/mobile-services-sync-pullasync-and-updatedat?forum=azuremobile
Thanks in Advance
How can I omit pulling data again if there is no update while all the Update At values are same time stamp? The issue is same as mentioned in below link. Do we still need to do one record update in order to fix this?
I have checked that this issue still exists. AFAIK, the PullAsync operation would pull 50 records (MaxPageSize by default is 50), then begin a transaction to insert / update the retrieved entities, then update the local __config table with the latest updatedAt timestamp, then try to retrieve next page records and execute the above processing again.
Note: The format of id column looks like this deltaToken|{table-name}|{query-id}.
The pull operation request would look like:
https://<app-name>.azurewebsites.net/tables/<table-name>?$filter=(updatedAt ge datetimeoffset'2018-02-21T08:58:45.446Z')&$orderby=updatedAt&$skip=0&$top=50&__includeDeleted=true
I assume that you could query the local __config table to retrieve the latest updatedAt value or query the related local table to retrieve the latest updatedAt value, then add a small time interval to the current updatedAt and explicitly specify the filter on UpdatedAt property with the previous updatedAt when using the incremental pull operation.
I have a system in which allows the user to apply for taking leaves. The system also credits leaves to each user's account, twice a year.
Now, the administrator has full authority over this whole system and, can cancel the and grant leaves.
To analyze whether a user has not exceeded all privileges extended to him, it is required that the admin should be shown a record of the credit and debit of leaves taking place in each user account, like a log.
Something like this:
Now, I have made a table as below, to house this data:
My query now is that how do i achieve this? I mean, what should be my sql query and how should i display it?
Should I create a Sql Server Agent job and display the data in a gridview? If yes, then how should I specify the steps for that.
My database has an employee table which stores the updated balance for each type of leave for every user. And the leave table houses the details of the requests made by the users. Basically, it stores all the details filled out in the leave application form.
I am confused as to how do I fetch the operations and changes occurring on these tables, for that is what is required to be displayed to the admin.
As per my understanding of your query, I have been shared my suggestion below :
1.My point of view ,you can get your expected output by using stored procedure in Database.
2.Because Hopefully You stored the values of employee information, leave type ,leave details are into separate table with the help of primary & foreign key constraints.
3.In the stored procedure, you can perform the following steps:
(1)Pass Input parameter : EmployeeId, FromDate, ToDate, HandledById (AdminId)
(2)Join all corresponding table with the help of Primary & foreign key Id.
(3)Select the appropriate column, Use aggregate function to find the leave.
(4)Use sub query in case of necessary as per your logic & table structure.
4.Then You can bind & display the data in gridview easily.
Do let me know if you need anything else.!
there is not much you need to do in sql for that. You can fetch the data that is to be displayed, but how you want it to display can be control on server side/Client side coding.
So its better you fetch data and user the ItemDataBoud event to control the representational part of the application.
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.