26
Session Session VDA308 VDA308 Achieve the Impossible: Achieve the Impossible: Use INSTEAD OF triggers in Use INSTEAD OF triggers in SQL Server 2000 to Deal SQL Server 2000 to Deal Transparently with No- Transparently with No- updateable Views updateable Views Fernando G. Guerrero Fernando G. Guerrero SQL Server MVP SQL Server MVP .NET Technical Lead .NET Technical Lead QA plc QA plc October 2002 October 2002

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

Embed Size (px)

DESCRIPTION

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

Citation preview

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

Session Session VDA308VDA308

Achieve the Impossible:Achieve the Impossible:Use INSTEAD OF triggers in SQL Use INSTEAD OF triggers in SQL Server 2000 to Deal Transparently Server 2000 to Deal Transparently

with No-updateable Viewswith No-updateable Views

Fernando G. GuerreroFernando G. GuerreroSQL Server MVPSQL Server MVP

.NET Technical Lead.NET Technical LeadQA plcQA plc

October 2002October 2002

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

VS .NET ConnectionsVS .NET Connections 2

Quick info about FernandoQuick info about Fernando(2 milliseconds)(2 milliseconds)

QA• MCSD, MCSE+Internet (W2K), MCDBA, MCT,

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

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

VS .NET ConnectionsVS .NET Connections 3

AgendaAgenda

• 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

33

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

VS .NET ConnectionsVS .NET Connections 6

A very silly INSTEAD OF triggerA very silly INSTEAD OF trigger

CREATE TRIGGER allSalesON OrdersINSTEAD OF INSERT, DELETE, UPDATEASPRINT 'Hello'

GO

UPDATE OrdersSET OrderDate = getdate()WHERE OrderID = 10259

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

VS .NET ConnectionsVS .NET Connections 7

Result of the very silly INSTEAD Result of the very silly INSTEAD OF triggerOF trigger

Hello

(1 row(s) affected)

• But nothing has been changed

• INSTEAD OF updating that row…

• … I printed ‘Hello’

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

VS .NET ConnectionsVS .NET Connections 8

Be careful with INSTEAD OF Be careful with INSTEAD OF triggerstriggers

• 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

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

VS .NET ConnectionsVS .NET Connections 9

INSTEAD OF triggers and INSTEAD OF triggers and TransactionsTransactions

• 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

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

VS .NET ConnectionsVS .NET Connections 10

INSTEAD OF triggers and LocksINSTEAD 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

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

VS .NET ConnectionsVS .NET Connections 11

Order of ExecutionOrder 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

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

VS .NET ConnectionsVS .NET Connections 12

So, are INSTEAD OF triggers any So, are INSTEAD OF triggers any good?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

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

VS .NET ConnectionsVS .NET Connections 13

A “little” problem with INSTEAD OF A “little” problem with INSTEAD OF UPDATE triggersUPDATE 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 [email protected]

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

VS .NET ConnectionsVS .NET Connections 14

Updateable and non-updateable Updateable and non-updateable viewsviews

• 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

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

VS .NET ConnectionsVS .NET Connections 15

What about primary keys?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

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

VS .NET ConnectionsVS .NET Connections 16

Some misleading info in BOL on Some misleading info in BOL on updateable viewsupdateable 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

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

VS .NET ConnectionsVS .NET Connections 17

What about joins?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

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

VS .NET ConnectionsVS .NET Connections 18

Using Instead of triggers to make Using Instead of triggers to make updateable a non-updateable viewupdateable 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

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

VS .NET ConnectionsVS .NET Connections 19

How to use this technique from How to use this technique from ADO.NET?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 ([email protected])

• As long as you define your own commands it works fine

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

VS .NET ConnectionsVS .NET Connections 20

What about the CommandBuilder?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

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

VS .NET ConnectionsVS .NET Connections 21

Applying this technique to specific Applying this technique to specific scenariosscenarios

• 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

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

VS .NET ConnectionsVS .NET Connections 22

Dealing transparently with vertically Dealing transparently with vertically partitioned tablespartitioned 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

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

VS .NET ConnectionsVS .NET Connections 23

Dealing transparently with Dealing transparently with horizontally partitioned tableshorizontally 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!

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

VS .NET ConnectionsVS .NET Connections 24

Updating computed columnsUpdating 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

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

VS .NET ConnectionsVS .NET Connections 25

Updating summary dataUpdating 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

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

VS .NET ConnectionsVS .NET Connections 26

Do you want to know more?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

2626

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

VS .NET ConnectionsVS .NET Connections 27

Do you want to know even Do you want to know even more?more?

• Visit the Microsoft public newsgroups:– msnews.microsoft.com/

microsoft.public.sqlserver.*– msnews.microsoft.com/

microsoft.public.dotnet.*

2727

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

VS .NET ConnectionsVS .NET Connections 28

Thank you! Questions?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:– [email protected]