Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Achieve the Impossible:Use INSTEAD OF triggers in SQL Server 2000 to Deal Transparently with No-updateable Views
1. Session
VDA308
Achieve the Impossible:
Use INSTEAD OF triggers in SQL
Server 2000 to Deal Transparently
with No-updateable Views
Fernando G. Guerrero
SQL Server MVP
.NET Technical Lead
QA plc
October 2002
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: www.callsql.com
• 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
2000
VS .NET Connections 2
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 happens
VS .NET Connections 33
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
action
VS .NET Connections 44
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 tables
VS .NET Connections 55
6. A very silly INSTEAD OF trigger
CREATE TRIGGER allSales
ON Orders
INSTEAD OF INSERT, DELETE, UPDATE
AS
PRINT 'Hello'
GO
UPDATE Orders
SET OrderDate = getdate()
WHERE OrderID = 10259
VS .NET Connections 6
7. Result of the very silly INSTEAD
OF trigger
Hello
(1 row(s) affected)
• But nothing has been changed
• INSTEAD OF updating that row…
• … I printed ‘Hello’
VS .NET Connections 7
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 done
VS .NET Connections 8
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
instead
VS .NET Connections 9
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
terminates
VS .NET Connections 10
11. Order of Execution
1. Default values
2. Instead of Trigger
3. Other constraints (Primary, check, unique)
4. Data is modified
5. IDENTITY and GUID values are evaluated
6. Indexes are maintained
7. Cascade Foreign Keys are applied, if any
8. After triggers run
VS .NET Connections 11
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 run
VS .NET Connections 12
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.com
VS .NET Connections 13
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 updated
VS .NET Connections 14
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
– Access
VS .NET Connections 15
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 example
VS .NET Connections 16
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
triggers
VS .NET Connections 17
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 user
VS .NET Connections 18
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 (sqlwish@microsoft.com)
• As long as you define your own commands it
works fine
VS .NET Connections 19
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 go
VS .NET Connections 20
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 scenarios
VS .NET Connections 21
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
table
VS .NET Connections 22
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. 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 all
VS .NET Connections 24
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 salespeople
VS .NET Connections 25
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:
– msnews.microsoft.com/microsoft.public.sqlserver.*
• Download the source code of this session from:
– http://www.callsql.com/en/articles
VS .NET Connections 26
26
27. Do you want to know even
more?
• Visit the Microsoft public newsgroups:
– msnews.microsoft.com/microsoft.public.sql
server.*
– msnews.microsoft.com/microsoft.public.dot
net.*
VS .NET Connections 27
27
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:
– http://www.callsql.com/en/articles
• You can contact me at:
– fernan@guerrerog.org
VS .NET Connections 28