Achieve the Impossible: Use INSTEAD OF triggers in SQL Server 2000 to Deal Transparently with No-updateable Views


Published on

some old tricks from 2002, which are no longer necessary these days

Published in: Technology
  • Be the first to comment

  • Be the first to like this

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Achieve the Impossible: Use INSTEAD OF triggers in SQL Server 2000 to Deal Transparently with No-updateable Views

  1. 1. SessionVDA308 Achieve the Impossible:Use INSTEAD OF triggers in SQLServer 2000 to Deal Transparently with No-updateable Views Fernando G. Guerrero SQL Server MVP .NET Technical Lead QA plc October 2002
  2. 2. Quick info about Fernando (2 milliseconds) • MCSD, MCSE+Internet (W2K), MCDBA, MCT,QA SQL Server MVP • This is where I work: QA, The best learning environment in Europe • Writing for SQL Sever Magazine and SQL Server Professional • This is my main web site: • This is my book (so far): – Microsoft SQL Server 2000 Programming by Example (ISBN : 0789724499, co-authored with Carlos Eduardo Rojas) • Currently writing on ADO.NET and SQL Server 2000VS .NET Connections 2
  3. 3. Agenda• INSTEAD OF triggers?• Updateable and non-updateable views• Using Instead of triggers to make a view updateable• How to use this technique from ADO.NET?• Applying this technique to specific scenarios• Note: slides are just a table of contents, is in the examples (with query plans and SQL Profiler) where you will learn what actually happensVS .NET Connections 33
  4. 4. INSTEAD OF triggers?• They execute instead of the requested action: – INSTEAD OF INSERT – INSTEAD OF UPDATE – INSTEAD OF DELETE• They are proactive (run before the action takes place)• Incompatible with cascade operations defined for the same object and action• Only one INSTEAD OF trigger per object and actionVS .NET Connections 44
  5. 5. INSTEAD OF triggers? (2)• NO, Nothing has been changed yet• NO, Constraints haven’t been checked yet• NO, IDENTITY values haven’t been generated yet• YES, DEFAULT values are applied to help you• NO, indexes haven’t been maintained yet• YES, you have access to the inserted and deleted tablesVS .NET Connections 55
  6. 6. A very silly INSTEAD OF triggerCREATE TRIGGER allSalesON OrdersINSTEAD OF INSERT, DELETE, UPDATEAS PRINT HelloGOUPDATE OrdersSET OrderDate = getdate()WHERE OrderID = 10259VS .NET Connections 6
  7. 7. Result of the very silly INSTEAD OF triggerHello(1 row(s) affected)• But nothing has been changed• INSTEAD OF updating that row…• … I printed ‘Hello’VS .NET Connections 7
  8. 8. Be careful with INSTEAD OF triggers• It is up to you to write the appropriate code that will run instead of the requested action• If you decide to do nothing in your code, NOTHING will be doneVS .NET Connections 8
  9. 9. INSTEAD OF triggers and Transactions• Inside the trigger you are always inside a transaction: – If you were inside a transaction already before the trigger started, @@TRANCOUNT remains unchanged – Otherwise @@TRANCOUNT returns 1• If you executed ROLLBACK inside the trigger, the entire transaction will be rolled back: – No need for rolling back this particular action – Inform the calling batch with an error and do nothing insteadVS .NET Connections 9
  10. 10. INSTEAD OF triggers and Locks• When the trigger starts execution: – No exclusive locks have been obtained by this particular action – Update locks has been obtained – Intent locks has been obtained at higher levels of granularity• As soon as the trigger perform any action locks will be obtained appropriately• Locks will be released when the transaction terminatesVS .NET Connections 10
  11. 11. Order of Execution1. Default values2. Instead of Trigger3. Other constraints (Primary, check, unique)4. Data is modified5. IDENTITY and GUID values are evaluated6. Indexes are maintained7. Cascade Foreign Keys are applied, if any8. After triggers runVS .NET Connections 11
  12. 12. So, are INSTEAD OF triggers any good?• They run when it is still time to decide• Less intrusive than AFTER triggers• Improve concurrency by avoiding exclusive locks as much as possible• Could produce more overhead than constraints, but less than after triggers• Perhaps better than stored procedures because you can’t avoid instead of triggers: they always runVS .NET Connections 12
  13. 13. A “little” problem with INSTEAD OF UPDATE triggers• You don’t have a RESEND, or DOIT, statement• Let’s see why this is important with this example• Feel free to send your wishes to sqlwish@microsoft.comVS .NET Connections 13
  14. 14. Updateable and non-updateable views• As a general rule a view is always updateable unless: – It is collapsed: • Uses UNION • Is the result of an aggregation – All its columns are read-only – Doesn’t contain an actual table in the FROM clause• UNION ALL views can be updateable if they are defined as partitioned views• As long as there is one column to update, the view can be updatedVS .NET Connections 14
  15. 15. What about primary keys?• A view doesn’t need a primary key or unique index to be updatable• Because UPDATE, INSERT or DELETE statements don’t need to reference primary keys at all• This is a limitation of the Visual Database Tools included in: – Enterprise Manager – Query Analyzer – Visual Studio – AccessVS .NET Connections 15
  16. 16. Some misleading info in BOL on updateable views• Derived columns make a view non updateable… Wrong! – Look at this example• Views can be updated as long as SQL Server knows how to translate changes to the underlying table… Wrong! unless – It is a properly formed partitioned view – It has defined the appropriate instead of triggers – Look at this exampleVS .NET Connections 16
  17. 17. What about joins?• Transact-SQL supports JOIN clause in the UPDATE, INSERT and DELETE statements• Therefore, a view defined with a JOIN clause is updateable as long as: – every statement updates one and only one table at a time – Or it has defined the appropriate instead of triggersVS .NET Connections 17
  18. 18. Using Instead of triggers to make updateable a non-updateable view• The instead of trigger runs first, before the actual modification is attempted• If you know the business meaning of the intended modification, you can write an instead of trigger to do it• The code inside the instead of trigger will modify actual tables, instead of the view itself• As long as the code inside the trigger is valid, the action will be valid as well• All this process is transparent to the userVS .NET Connections 18
  19. 19. How to use this technique from ADO.NET?• The UI doesn’t support this feature, and the DataAdapter will be unable to create the InsertCommand, UpdateCommand and DeleteCommand: – It’s a problem with connection settings (ARITHABORT) that could be fixed by the VS or SQL guys (• As long as you define your own commands it works fineVS .NET Connections 19
  20. 20. What about the CommandBuilder?• It doesn’t support updateable views through instead of triggers unless: – You set the AIRTHABORT ON connection option by code – You create a UNIQUE CLUSTERED INDEX on that view – You use the NOEXPAND option after the view name – There you goVS .NET Connections 20
  21. 21. Applying this technique to specific scenarios• Dealing transparently with vertically partitioned tables• Dealing transparently with horizontally partitioned tables• Updating computed columns• Updating summary data• I’ll show you in detail one example of each one of these scenariosVS .NET Connections 21
  22. 22. Dealing transparently with vertically partitioned tables• DELETE: – Don’t do it unless you know for sure what makes sense• INSERT: – Which table you want to insert to? – Write one statement per table• UPDATE: – Write one statement per underlying tableVS .NET Connections 22
  23. 23. Dealing transparently with horizontally partitioned tables• Define them as partitioned views and leave SQL Server alone, he will do it properly for you• In any other case, write the appropriate code to select which actual table to affect• Have a clear partition criteria!VS .NET Connections 23
  24. 24. Updating computed columns• Make sure the formula has a valid reverse formula which produces unique valid results• Don’t expect the UI to be able to deal with it at allVS .NET Connections 24
  25. 25. Updating summary data• You should know what means updating totals ;-)• It could be useful for increasing budget on several unfinished sections with a single change on total budget• Also for spreading changes on target sales for all salespeopleVS .NET Connections 25
  26. 26. Do you want to know more?• “Inside SQL Server 2000” (Kalen Delaney, MSPress)• “Advanced Transact-SQL for SQL Server 2000” (Itzik Ben-Gan & Tom Moreau, APress)• “SQL Server 2000 Programming” (Robert Vieira, WROX)• “Microsoft SQL Server 2000 Programming by Example” (Fernando G. Guerrero & Carlos Eduardo Rojas, QUE)• SQL Server 2000 Resource Kit (MSPress & TechNet)• Visit the Microsoft public newsgroups: –*• Download the source code of this session from: – VS .NET Connections 26 26
  27. 27. Do you want to know even more?• Visit the Microsoft public newsgroups: – server.* – net.*VS .NET Connections 27 27
  28. 28. Thank you! Questions? • Please drop off your session evaluations in the basket at the back of the room! • Your comments are greatly appreciated! • Download the source code of this session from: – • You can contact me at: – fernan@guerrerog.orgVS .NET Connections 28