I am trying to create a generic trigger in SQL Server which can copy all column data from Table A and insert them in corresponding fields in Table B.
There are few problems I am facing.
I need this copy to occur under three conditions : INSERT, DELETE and UPDATE.
The trigger needs to be triggered after CUD operations. using AFTER throws SQL error saying ntext etc are not supported in inserted. How do I resolve this error?
Instead of if used can work for INSERT but not for delete. Is there a way to do this for delete operations?
Is there a way I can write a generic code inside the trigger which can work for all sorts of tables (we can assume that all the columns in table a exists in column b)
I am not well versed with triggers or for that matter DDL in SQL Server.
Appreciate if some can provide me some solutions.
Thanks
Ben
CREATE TRIGGER (Transact-SQL)
Use nvarchar(max) instead of ntext.
You can have an instead of trigger for delete.
You can have one trigger that handles insert/update/delete for one table but you can not connect a trigger to more than one table.
Related
I want to add +1 for views column when a visitor view a page. I decided to make it using trigger, but i don't know how to make a trigger on select, I see examples on delete, update and insert but no one mentioned select. anyone can help me with simple example?
There is no such thing as a trigger for 'SELECT' in SQL Server. As an alternative you could create a stored procedure that does the SELECT and UPDATEs your view counts.
short answer is no,there is nothing like trigger on SELECT.moreover
If the data you have if so sensitive and you want to implement access audit in t-sql (which not the best design idea), you can do the following:
Remove SELECT access to the table from all users
Create stored procedure to retrieve data from the table
Implement custom audit inside of the above stored proc.
you can view this link here to read about it more
are we using SQL Server Views for only Getting(SELECT) the Results or is there any other operations can be performed by using VIEWS.
My Question is i am Trying to Insert some New Records into my table by using Views, is it possible to do this operation by using this Views.
You can, in fact, insert, update or delete using a View. From MSDN:
You can modify the data of an underlying base table through a view, in
the same manner as you modify data in a table by using UPDATE,
INSERT and DELETE statements or by using the bcp utility and BULK INSERT statement.
However, there are restrictions on how you can actually do this. You can read the details on MSDN. In short, the view must only reference columns from one base table, must not contain any computed or derived columns and must not contain grouping clauses.
No, a view is a "virtual table", so you can't execute operations like insert and update.
You have to apply the changes into the original table then the view will reflect the changes.
View
If you are using MS SQL Server, you can use "Stored Procedure". Or similar in other DBMS.
i have a table named "LogDelete" to save information about users that deleted any rows on any tables. the table fields are like this :
create table LogDelete
(
pk int identity(1,1) primary key,
TableName varchar(15),
DeleteUser nvarchar(20),
DeleteDate datetime
)
Actually i wanna create a trigger that fire on all tables on update action that on every update write proper information on LogDelete Table,
at now i use a stored procedure and call it on every update action on my tables.
Is there a way to do this?
No. There are 'event' triggers, but they are mainly related to loggin in. These kinds of triggers are actually DDL triggers, so they are not related to updating data, but to updating your database scheme.
Afaik, there is no trigger that fires on every update. That means that the way you are handling it now, through a stored procedure, is probably the best way. You can create triggers on each table to call the procedure and do the logging.
You might even write a script that creates all those triggers for you in one run. That will make the initial creating and later updating of the triggers a bit easier.
Here is some MSDN documentation, which says (in remarks about DML triggers):
CREATE TRIGGER must be the first statement in the batch and can apply to only one table.
There is no magic solution for your request, not such a thing as event triggers to all DML (INSERT, UPDATE, DELETE) as you like, but there are some alternatives that you can consider:
If you are using SQL Server 2008 or after, the best thing you could use is CDC (Change Data Capture), you can start with this article by Dave Pinal, I think this will be the best approach since it is not affected by any change in structures.
Read the log file. You'll need analyze it find each DML activity in the log and so you could build an unified operation to log the changes that you need, obviously this is not on-line and not trivial
Same as option two but using traces on all the DML activities. The advantage of this approach is that it can be almost online and it will not require analyzing the log file, you'll just need to analyze a profiler table.
I've a self join table when I delete or update it's id I want to delete or update all the direct and indirect affected records
SQL server does not allow this type of cycle cascading I've decided to use triggers but this triggers will file recursively and they will be terminated at 34 level and I don't know the depth of records and event I disable the trigger and re enable it after completing the process how can I construct a SQL statement that achieve this logic?
Because your table has circular references, a regular SQL statement won't suffice. Instead, you could write SQL using the following recipe:
create a temporary table for the IDs you want to process.
Create an SQL query that inserts the referenced IDs into the temp table. Make sure you do not insert duplicates.
Put the query in a loop and use counters to determine if records have been added. If no extra records were added, exit the loop.
Create your update statement that uses the IDs in the temp table.
Drop the temp table.
You should use a construct like nested sets for that kind of data: http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/
Edit: Ok, with circular references you'll have a problem... But dependent on your data it still may help?
I erroneously delete all the rows from a MS SQL 2000 table that is used in merge replication (the table is on the publisher). I then compounded the issue by using a DTS operation to retrieve the rows from a backup database and repopulate the table.
This has created the following issue:
The delete operation marked the rows for deletion on the clients but the DTS operation bypasses the replication triggers so the imported rows are not marked for insertion on the subscribers. In effect the subscribers lose the data although it is on the publisher.
So I thought "no worries" I will just delete the rows again and then add them correctly via an insert statement and they will then be marked for insertion on the subscribers.
This is my problem:
I cannot delete the DTSed rows because I get a "Cannot insert duplicate key row in object 'MSmerge_tombstone' with unique index 'uc1MSmerge_tombstone'." error. What I would like to do is somehow delete the rows from the table bypassing the merge replication trigger. Is this possible? I don't want to remove and redo the replication because the subscribers are 50+ windows mobile devices.
Edit: I have tried the Truncate Table command. This gives the following error "Cannot truncate table xxxx because it is published for replication"
Have you tried truncating the table?
You may have to truncate the table and reset the ID field back to 0 if you need the inserted rows to have the same ID. If not, just truncate and it should be fine.
You also could look into temporarily dropping the unique index and adding it back when you're done.
Look into sp_mergedummyupdate
Would creating a second table be an option? You could create a second table, populate it with the needed data, add the constraints/indexes, then drop the first table and rename your second table. This should give you the data with the right keys...and it should all consist of SQL statements that are allowed to trickle down the replication. It just isn't probably the best on performance...and definitely would impose some risk.
I haven't tried this first hand in a replicated environment...but it may be at least worth trying out.
Thanks for the tips...I eventually found a solution:
I deleted the merge delete trigger from the table
Deleted the DTSed rows
Recreated the merge delete trigger
Added my rows correctly using an insert statement.
I was a little worried bout fiddling with the merge triggers but every thing appears to be working correctly.