IT tutorials
 
Database
 

SQL Server : Common Problems with Data Integrity - Enforcing Data Integrity Using Triggers (part 3) - Accidentally overriding changes made by other triggers

6/11/2013 7:40:31 PM
- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
Sometimes triggers do not fire

Even if we have a "bug-free" trigger, it does not mean that it will fire every time our data changes. There are certain settings and actions that can prevent a trigger from firing:

  • disabling a trigger

  • use of the IGNORE_TRIGGERS hint in an INSERT statement when the BULK option is used with OPENROWSET

  • when the nested triggers or recursive_triggers setting prevents a trigger from firing

  • the TRUNCATE TABLE command does not fire FOR DELETE or INSTEAD OF DELETE triggers

  • when the BULK INSERT command runs without the FIRE_TRIGGERS option

  • if a trigger is dropped and later recreated, then any modifications made to the table in the interim will not have been subject to the trigger's logic

  • if a table is dropped and recreated

  • when parent and child tables are in different databases, and an old backup of the parent database is restored.

The final item in this list requires some elaboration. When parent and child tables are in different databases, we cannot use a FOREIGN KEY constraint to ensure that there are no orphan rows in our child table. In this case, it is very tempting to use triggers. However, suppose that we need to restore the database that contains our parent table, after a failure. Clearly, when a database is restored, triggers do not fire. This means that nothing protects us from the following scenario:

  • back up the parent database

  • add a new parent row

  • add some child rows referring to that new parent row

  • restore the parent database to the backup that does not have the latest parent row.

All of this means that we cannot necessarily assume our trigger fires every time the table it protects is modified. If our system is subject to any of the cases when triggers do not fire, then we need to have a script that will clean up our data. For example, if we have a parent and a child table in different databases, we need a script that deletes orphan rows.

Accidentally overriding changes made by other triggers

When using triggers, it is important to realize that it is possible to have more than one trigger on one and the same table, for one and the same operation. For example, consider the FOR UPDATE trigger shown in Listing 6.

Listing 12. Creating a second FOR UPDATE trigger, Items_EraseBarcodeChangeLog, on table Items.

This new trigger creates without any warnings, and we may not realize that we already have another FOR UPDATE trigger on the same table. We can rerun the script in Listing 4 and see for ourselves that this new trigger and the previous one do the opposite things and, as such, they should not coexist. Of course, this is a simplified example, but the point is that when we have multiple triggers for the same operation on the same table, then it's a recipe for bugs and data integrity issues.

As a defensive technique, before you start coding a trigger, it's well worth running a quick check to find out if any other triggers exist on the target table. To be even safer, after adding a trigger it is a good practice to check for multiple triggers on the same table for the same operation. Listing 13 shows a script that finds all the tables on which there is more than one trigger for the same operation.

Listing 13. Selecting all the tables on which there is more than one trigger for the same operation.

Multiple triggers for the same operation, on the same table, not only introduce the chances of conflicting changes, they also introduce the chance of redundant actions, or of unwanted and maybe unknown dependencies on undocumented execution orders.

If we want to make sure that there is not more than one trigger for one operation on one table, we can wrap the query in Listing 13 in a unit test and have our test harness verify that it never returns anything.

Before moving on to other examples, let us get rid of the triggers we no longer need, as shown in Listing 14.

Listing 14. Dropping the triggers.

Problems with triggers under snapshot isolation levels

When our triggers are selecting from other rows or other tables, in some cases we are implicitly assuming that they will not run under snapshot isolation level. In such cases, it is necessary to use the READCOMMITTEDLOCK hint to eliminate this assumption.

 
Others
 
 
 
Top 10
 
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
Technology FAQ
- Is possible to just to use a wireless router to extend wireless access to wireless access points?
- Ruby - Insert Struct to MySql
- how to find my Symantec pcAnywhere serial number
- About direct X / Open GL issue
- How to determine eclipse version?
- What SAN cert Exchange 2010 for UM, OA?
- How do I populate a SQL Express table from Excel file?
- code for express check out with Paypal.
- Problem with Templated User Control
- ShellExecute SW_HIDE
programming4us programming4us