I have a windows application form. The table is called messages and whenever user inserts updates or deletes a message, the date/timestamp is stored in the column UserAction.
This column information should be retrieved and shown in the UI as a link. Clicking that link has an action and the link should be seen as read.
Can someone help me in giving some ideas to achieve this action?
Thanks in advance.
I am not sure how you can trigger the event from database and display the details in the UI but I think below is doable:
Add INSERT/DELETE triggers in your table with the code to insert data in UserAction table.
Build an UI which reads the data from UserAction and displays in the UI.
You may want to refresh your UI to refresh the data from database UserAction at certain interval.
This way, you UI will poll for any changes UserAction at certain interval and refresh the page with refreshed data.
You can use Query Notifications, although there are some limitations to what can be monitored.
SQL Server 2005 introduced query notifications, new functionality that allows an application to request a notification from SQL Server when the results of a query change. Query notifications allow programmers to design applications that query the database only when there is a change to information that the application has previously retrieved.
This functionality is exposed via the SqlDependency class. You should review the Remarks section as part of evaluating whether Query Notifications are for you:
SqlDependency was designed to be used in ASP.NET or middle-tier services where there is a relatively small number of servers having dependencies active against the database. It was not designed for use in client applications, where hundreds or thousands of client computers would have SqlDependency objects set up for a single database server. If you are developing an application where you need reliable sub-second notifications when data changes, review the sections Planning an Efficient Query Notifications Strategy and Alternatives to Query Notifications in the Planning for Notifications topic in SQL Server Books Online.
You could try something like this:
CREATE TRIGGER dbo.trMessagesUpdateTimeStamp
ON dbo.Messages
FOR INSERT, UPDATE, DELETE
AS
UDPATE dbo.Messages
SET UserAction = GETDATE()
FROM Inserted i
WHERE dbo.YourTableHere.ID = i.ID
Points to check out:
the INSERT case could easily more easily be handled by a DEFAULT constraint on the UserAction column - that way, upon INSERT the defined default value (e.g. GETDATE()) would be inserted
you need to be able to join the Inserted pseudo table that holds all the rows that were modified by the last statement (and this can be multiple rows) with the Messages table - I've assumed here that you have some kind of an ID column that serves as primary key on Messages - adapt this as needed.
This handles the database part of the story - I'm not quite sure from your question what you want to do in the UI ...
Related
I'm working with C# and Microsoft SQL Server Express 2008. The table will be populated by a remote hardware so i don't have control over SQL command for the insert. Can I set SQL server to generate an event on insert catchable in C# (or other .NET) application?
There are many ways to do that if i would you then i will do something like....
Write insert Trigger on that table and in that trigger call exe
For example :
declare #sqlcmd varchar(200)
SET #SQLCmd = 'c:\dba\sampl_2.exe'
EXEC master..xp_cmdshell #SQLCmd , no_output
and in that exe you can handle whatever you want...
Probably you are looking for: SqlDependency class.
But as far as I remember SQL Server Express does not support SqlDependency features.
If so, I would create one more column, something like "IsProcessed" and once the app processes the row set it to true or something. By using this approach you can query the table using where clause: where IsProcessed is null.
There are several options to do something like this. It's easy to set up an insert trigger in SQL that effectively fires an event during which you can carry out any number of tasks: send a message, write to another table, write to a log. etc.
For me, the question is how best to you get your C# program to "listen" for this trigger event.
One option might be to set up a little WCF program as as listener that responds to messages sent by SQL server when the insert trigger fires. Here's a link to a CodeProject piece about doing something like that.
http://www.codeproject.com/Articles/21149/Invoking-a-WCF-Service-from-a-CLR-Trigger
It's interesting how this kind of question emerges on SO from time to time. And there is still no explicit unique answer that can be given in all situations.
Actually, the question asks on how should a multiple-insert-event be captured in SQL server for a particular table. I hope it is a particular table, because in SQL Server itself there isn't a method to listen DML changes to all tables (something like * from tables) at once. If you want, you can create N triggers (it could be done e.g. using dynamic SQL) on N tables and listen to these, but what if a new table gets added?
Let's think we have a specific table MyTable where we would like to listen for INSERT, UPDATE and DELETE events. One way to do it is implementing a trigger (speciffically AFTER trigger, since INSTEAD OF triggers are not made for this case). Another option is a query notification. But which one do you really need?
Query notification implies that you have to code .NET application. Trigger implies all that is trigger-related: you can have TSQL code, you can even call a web service from your database using CLR trigger. But - what do you need?
So, if you really need to react in the way to just write a log record in a table, use plain old trigger. Otherwise you should think: why do you need really need C# application here?
For example, say you need to catch a delete statement and serialize all deleted rows in XML format to the file system in a file. I would use CLR trigger in EXTERNAL_ACCESS mode to be able to create file and save information to disk.
I have ERP database "A" has only read permission, where i cant create trigger on the table.
A is made for ERP system (Unknown Program for me ). I have another Database "B" that is private to my application this application work on both databases. i want to reflect A's changes(for any insert/Update/Delete) instantly to B.
Is there any Functionality in c# that can work exactly as trigger works in database???
You have few solutions, best one depends on which kind of database you have to support.
Generic solution, changes in A database aren't allowed
If you can't change master database and this must work with every kind of database then you have only one option: polling.
You shouldn't check too often (so forget to do it more or less instantly) to save network traffic and it's better to do in in different ways for insert/update/delete. What you can do depends on how database is structured, for example:
Insert: to catch an insert you may simply check for highest row ID (assuming what you need to monitor has an integer column used as key).
Update: for updates you may check a timestamp column (if it's present).
Delete: this may be more tricky to detect, a first check would be count number of rows, if it's changed and no insert occured then you detected a delete else just subtract the number of inserts.
Generic solution, changes in A database are allowed
If you can change the original database you can decrease network traffic (and complexity) using triggers on database side, when a trigger is fired just put a record in an internal log table (just few columns: one for the change type, one for affected table, one for affected record).
You will need to poll only on this table (using a simple query to check if number of rows increased). Because action (insert/update/delete) is stored in the table you just need to switch on that column to execute proper action.
This has a big disadvantage (in my point of view): it puts logic related to your application inside the master database. This may be terrible or not but it depends on many many factors.
SQL Server/Vendor specific
If you're application is tied to Microsoft SQL Server you can use SqlDependency class to track changes made. It works for SS only but I think there may be implementations for other databases. Disadvantage is that this will always bee specific to a specific vendor (so if A database will change host...you'll have to change your code too).
From MSDN:
SqlDependency was designed to be used in ASP.NET or middle-tier services where there is a relatively small number of servers having dependencies active against the database. It was not designed for use in client applications, where hundreds or thousands of client computers would have SqlDependency objects set up for a single database server.
Anyway if you're using SQL Server you have other options, just follow links in MSDN documentation.
Addendum: if you need a more fine control you may check TraceServer and Object:Altered (and friends) classes. This is even more tied to Microsoft SQL Server but it should be usable on a more wide context (and you may keep your applications unaware of these things).
You may find useful, depending on your DBMS:
Change Data Capture (MS SQL)
http://msdn.microsoft.com/en-us/library/bb522489%28v=SQL.100%29.aspx
Database Change Notification (Oracle)
http://docs.oracle.com/cd/B19306_01/appdev.102/b14251/adfns_dcn.htm
http://www.oracle.com/technetwork/issue-archive/2006/06-mar/o26odpnet-093584.html
Unfortunately, there's no SQL92 solution on data change notification
Yes There is excellent post are here please check this out..
http://devzone.advantagedatabase.com/dz/webhelp/advantage9.1/mergedprojects/devguide/part1point5/creating_triggers_in_c_with_visual_studio_net.htm
If this post solve your question then mark as answered..
Thanks
I want to create application which update their control properties at the time of table values updated from database by another user. i find a solution by refreshing a control every second by help of timer, but it is not good i want to change after updating a values not to request every second SQL Server?
Basically you need to have SQL post when the table is updated. This called a push model (the opposite is a pull model which you are now doing).
You can use SqlDependency for this. See http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldependency%28v=vs.100%29.aspx
However, there is some overhead associated with a push approach. Many apps just do a query every n seconds (3 - 10) and then only update the control when the properties changed.
It really is a optimisation trade off. Is making a network request (pull model) more "expensive" than having SQL server doing the trigger and then send the update message (push model)?
You can use SqlDependency for this, without polling.
Implementing SQL Server 2005 Query Notifications in C# Windows Application
I have a table where I want to Log activities of some part of my application. A record will be inserted (may be updated in future) in this table when record inserted/updated in some other table.
E.g.
If record is inserted in Orders table
an entry will be inserted in Log
table.
If record is inserted in Booking
table an entry will be inserted in
Log table.
if record is updated in Customers
table an entry will be inserted in
Log table if Log table does not have
an entry for this customer.
etc..
Should I use Triggers on these tables to add records in Log table or should I have a common method in my code and call that method whenever insert/update activity occurs?
I have to do this activity on some part of my applications so there can be more than 20 tables on which I will be adding trigger or from couple of different locations from where I will call method.
I am using SQL Server 2005 and C#
What is better, Trigger or A method?
Method is better option than Trigger.
Triggers are generally
- performance heavy
- Less visible in the code, ie are hidden away
- More difficult to debug & Maintain.
- Limits on values to be passed to the log table
A method would give you lots of advantages in terms of optimizing the code, and extending the logic and easier to maintain
As this seems an important task I would use triggers inside the RDBMS to ensure that not only your application causes the logs to be created.
In case someone has the ability to update the database without your app by using TOAD, SSMS, Query Ananlyzer etc tec, a trigger would be better
it is never too late for such questions ,
in General , triggers reduce the round trip of your DB and code ,
in your case , to do this in C# you will need 2 trips for each action ,one for the action (Insert) and one for the log action , and of course you need to do a lot of handling for exceptions in your code so if the record is not inserted you handle this and also you log different action of failure
as trigger ,you send the data once to the server and all actions and handling are done there with no extra connections
this is useful specially now that every thing is shared and connections polls are limited .
Every change of data in some row in database should save the previous row data in some kind of history so user can rollback to previous row data state. Is there any good practice for that approach? Tried with DataContract and serializing and deserializing data objects but it becomes little messy with complex objects.
So to be more clear:
I am using NHibernate for data access and want to stay out off database dependency (For testing using SQL server 2005)
What is my intention is to provide data history so every time user can rollback to some previous versions.
An example of usage would be the following:
I have a news article
Somebody make some changes to that article
Main editor see that this news has some typos
It decides to rollback to previous valid version (until the newest version is corrected)
I hope I gave you valid info.
Tables that store changes when the main table changes are called audit tables. You can do this multiple ways:
In the database using triggers: I would recommend this approach because then there is no way that data can change without a record being made. You have to account for 3 types of changes when you do this: Add, Delete, Update. Therefore you need trigger functionality that will work on all three.
Also remember that a transaction can modify multiple records at the same time, so you should work with the full set of modified records, not just the last record (as most people belatedly realize they did).
Control will not be returned to the calling program until the trigger execution is completed. So you should keep the code as light and as fast as possible.
In the middle layer using code: This approach will let you save changes to a different database and possibly take some load off the database. However, a SQL programmer running an UPDATE statement will completely bypass your middle layer and you will not have an audit trail.
Structure of the Audit Table
You will have the following columns:
Autonumber PK, TimeStamp, ActionType + All columns from your original table
and I have done this in the following ways in the past:
Table Structure:
Autonumber PK, TimeStamp, ActionType, TableName, OriginalTableStructureColumns
This structure will mean that you create one audit table per data table saved. The data save and reconstruction is fairly easy to do. I would recommend this approach.
Name Value Pair:
Autonumber PK, TimeStamp, ActionType, TableName, PKColumns, ColumnName, OldValue, NewValue
This structure will let you save any table, but you will have to create name value pairs for each column in your trigger. This is very generic, but expensive. You will also need to write some views to recreate the actual rows by unpivoting the data. This gets to be tedious and is not generally the method followed.
Microsoft have introduced new auditing capabilities into SQL Server 2008. Here's an article describing some of the capabilities and design goals which might help in whichever approach you choose.
MSDN - Auditing in SQL Server 2008
You can use triggers for that.
Here is one example.
AutoAudit is a SQL Server (2005, 2008)
Code-Gen utility that creates Audit
Trail Triggers with:
* Created, Modified, and RowVerwsion (incrementing INT) columns to table
* view to reconstruct deleted rows
* UDF to reconstruct Row History
* Schema Audit Trigger to track schema changes
* Re-code-gens triggers when Alter Table changes the table
http://autoaudit.codeplex.com/
Saving serialized data always gets messy in the end, you're right to stay away from that. The best thing to do is to create a parallel "version" table with the same columns as your main table.
For instance, if you have a table named "book", with columns "id", "name", "author", you could add a table named "book_version" with columns "id", "name", "author", "version_date", "version_user"
Each time you insert or update a record on table "book", your application will also insert into "book_version".
Depending on your database system and the way you database access from your application, you may be able to completely automate this (cfr the Versionable plugin in Doctrine)
One way is to use a DB which supports this natively, like HBase. I wouldn't normally suggest "Change your DB server to get this one feature," but since you don't specify a DB server in your question I'm presuming you mean this as open-ended, and native support in the server is one of the best implementations of this feature.
What database system are you using? If you're using an ACID (atomicity, consistency, isolation, durability) compliant database, can't you just use the inbuilt rollback facility to go back to a previous transaction?
I solved this problem very nice by using NHibernate.Enverse
For those intersted read this:
http://nhforge.org/blogs/nhibernate/archive/2010/07/05/nhibernate-auditing-v3-poor-man-s-envers.aspx