Vous êtes sur la page 1sur 24

16/2/2015

LespetitspapiersdeSQLproTechniquesdesSGBDR
Forums Tutoriels Magazine FAQs Blogs Projets Chat Newsletter tudes Emploi Club Contacts

Accueil

ALM
SGBD

Java

4D

.NET

Dv.Web

Access

EDI

BigData

AccueilSGBD

Programmation
DB2

ForumsSGBD

Firebird

FAQsSGBD

SGBD

Office

InterBase

Solutionsd'entreprise

MySQL

TutorielsSGBD

SQL

NoSQL

Applications

PostgreSQL

OutilsSGBD

Oracle

Mobiles
Sybase

Systmes

SQLServer

LivresSGBDetSQL

Aquoiasert???
Aencroirecertainsintgristes(deMySQLpournepasleciter)certainsdeslmentsdesbasesdedonness'avreraientparfaitementinutile.
Auxortiesdonclesintgritsrfrentielles,lessousrequtes,lesrequtesensemblistes,lestriggers,lesprocduresstockesetautresUDF...
Brefunretourenarriresurvingtannnespendantlesquelleslesbasesdedonnesrelationnellesn'ontcesssdeprogresser.
Estilrellementpossibledesepasserdetelslment?
Cetarticlefaitlepointsurlaquestion,etenprimefaittomberlemythedelarapiditdeMySQL!
Articlelu6076fois.
L'auteur
SQLPro
L'article
Publile18avril2004
Prambule
Publicvis:intermdiaire
Ungestionnairedebasesdedonnesestunlogicielcapabledetraiterdesdonnesstructuresdansuncontextedeconcurrence.C'estainsi
Lienssociaux
queplusieursutilisateursdoiventpouvoiraccderauxdonnesetlesmodifiersansqu'ilenrsultededgtscausspardesmanipulationsqui
s'enchevtrent.C'estcequel'onappellelerespectdel'intgritdesdonnes...
NousallonsvoirlestechniquesqueproposelanormeSQLafindegarantirlabonnemarched'unebasededonnesrelationnelle.

1.Aquoiserventlestransactions?

Lestransactionssontlaclefmmedetouteproblmatiqued'accsconcurrent.Mmelorsdesimpleslectures,leSGBDRdoitpouvoirassurer
lerespectdelacohrencedesdonnesdansletemps.Bienentendu,lorsdemodificationsdedonnes,lestransactionsserventgarantirque
toutsoitmenbiensansqu'ilenrsultelamoindreanomalie,oul'inverse,siuneanomalieseproduit,derevenirl'tatantrieur,c'est
direl'tatqu'avaientlesdonnesavantledmarragedelatransaction.
Pourunaperurapidedelachose,onpeutlirel'articledeHenriCesbronLavausurlesujetl'URL:
http://www.developpez.com/hcesbronlavau/Transactions.htm
Lanormedfinideuxlmentspourpiloterlestransactions:
latransactionellemme
etsa"permabilit"enverslestransactionsexcutesenparallle
Latransactionpermetdedfinirl'atomicitdutraitementconsidr.
Untraitementatomiqueestuntraitementquiestconsidrcommefonctionnantentoutourien:soittouteslesoprationsrelativesaux
traitementssontexcutes,soitellessonttoutesannulesetlesdonnesreviennentdansl'tatantrieurquiprcdaitjustelatransaction.
Lanotiond'"atomique"vientdugrec.L'atomepourlesgrectaitlapluspetitepartieinscabledelamatire.Autrementditonnepouvaitpas
couperplusfinementlamatire.Uncodeatomiqueestdoncunprogrammequis'excutesansjamaistreinterrompuparunprocessus
concourrant.Iladoncl'exclusivitdesressourcespendanttoutletempsdesonexcution.
Pourmieuxcomprendreleproblme,prenonsunexemplesimple.Soitlestables:

Slectionnez
CREATETABLET_VOL
(VOL_IDINTEGER,
VOL_REFERENCECHAR(6),
VOL_DATEDATE,
VOL_PLACES_LIBRESINTEGER)

Slectionnez
CREATETABLET_CLIENT_VOL
(CLI_IDINTEGER,
VOL_IDINTEGER,
VOL_PLACE_PRISEINTEGER)

Slectionnez
INSERTINTOT_VOLVALUES(1,'AF714',7)
INSERTINTOT_VOLVALUES(2,'AF812',6)
INSERTINTOT_VOLVALUES(4,'AF325',258)

Slectionnez
INSERTINTOT_CLIENT_VOLVALUES(7,1,2)
INSERTINTOT_CLIENT_VOLVALUES(82,4,1)

Unclientdontlaclefest77,veutprendre5placessurlevol2.
Deuxrequtessontexcuter.LapremirevadcompterlenombredeplacedelatableT_VOLetlasecondevainsrerunelignedansla
tableT_CLIENT_VOLpourcenouveauclient.Apriorilesrequtessonttrssimpled'expression:

Slectionnez
UPDATET_VOL
SETVOL_PLACES_LIBRES=VOL_PLACES_LIBRES5
WHEREVOL_ID=2
INSERTINTOT_CLIENT_VOLVALUES(77,2,5)

http://sqlpro.developpez.com/cours/sqlaz/techniques/

1/24

16/2/2015

LespetitspapiersdeSQLproTechniquesdesSGBDR
Apparemmenttoutmarchebien...Saufquenousn'avonspaspensaucontextedeconcurrence.Etsiunautreutilisateurfaituntraitement
similaireaummemoment?Quesepassetil?Bienentendujevoisd'avancedesvoixs'levantendisantquec'estquasimentimpossible,
parcequecelasejouequelquesmillimesdeseconde...Maiseninformatique,surtoutaujourd'hui1/1000edesecondec'est200instructions
machine!!!Donc,concurrenceilpeutyavoir,etilyauracertainementunjouroul'autre...
Unepremireideestdetestersirellementilyabienaumoins5placeslibres...
D'olecodesuivant:

Slectionnez
if(SELECTVOL_PLACES_LIBRES
FROMT_VOLWHEREVOL_ID=2)>=5
then
begin
UPDATET_VOL
SETVOL_PLACES_LIBRES=VOL_PLACES_LIBRES5
WHEREVOL_ID=2
INSERTINTOT_CLIENT_VOLVALUES(77,2,5)
end

Nanmoins,toutmomentjusteaprslebeginoul'updatelesdonnespeuventchangeretconduirelacatastrophe...
tudionslecasoudeuxprocessusconcurrenteffectuedesrequtessimilairesetajoutonsleclient88quivademander3placessurlevol2...

Slectionnez
T1if(SELECTVOL_PLACES_LIBRES
FROMT_VOLWHEREVOL_ID=2)>5
then
begin

T3UPDATET_VOL
SETVOL_PLACES_LIBRES=VOL_PLACES_LIBRES5
WHEREVOL_ID=2

T5INSERTINTOT_CLIENT_VOLVALUES(77,2,5)
end

Slectionnez

T2if(SELECTVOL_PLACES_LIBRES
FROMT_VOLWHEREVOL_ID=2)>3
then
begin

T4UPDATET_VOL
SETVOL_PLACES_LIBRES=VOL_PLACES_LIBRES3
WHEREVOL_ID=2
T6INSERTINTOT_CLIENT_VOLVALUES(88,2,3)
end

VoicilecontenudestablespourlestempsT1T6pourlevol2etlesclients77et88:

Slectionnez
Temps T_VOL:
VOL_IDVOL_REFERENCEVOL_PLACES_LIBRES

T1

Slectionnez

Slectionnez
T_CLIENT_VOL:
CLI_IDVOL_IDVOL_PLACES_PRISES

2AF8126

T2

Slectionnez

2AF8126

T3

Slectionnez

2AF8121

T4

Slectionnez

2AF8122

T5

T6

Slectionnez

Slectionnez

2AF8122

7725

Slectionnez
2AF8122

Slectionnez
7725
8823

Nousavonsgnrdesplacesngativesetsurbookl'avion.

1.1.Transactionoucodeclient?
Esttilpossibledecontournerleproblmeparuncodepluttqueparunetransaction?Hlasnon,carchaquefoisquenoustesteronsnous
pouvonsavoirunautreordreSQLquis'intercale.Parexemplel'idederenverserlavapeursinousavonsgnrdesplacesngativesest
biententante...

http://sqlpro.developpez.com/cours/sqlaz/techniques/

Slectionnez

2/24

16/2/2015

LespetitspapiersdeSQLproTechniquesdesSGBDR
Slectionnez
T1if(SELECTVOL_PLACES_LIBRES
FROMT_VOLWHEREVOL_ID=2)>5
then
begin

T3UPDATET_VOL
SET VOL_PLACES_LIBRES=

VOL_PLACES_LIBRES5
WHEREVOL_ID=2

T5if(SELECTVOL_PLACES_LIBRES
FROMT_VOLWHEREVOL_ID=2)<0

T7then
begin
UPDATET_VOL
SETVOL_PLACES_LIBRES=

VOL_PLACES_LIBRES+5
WHEREVOL_ID=2
return
end

T9INSERTINTOT_CLIENT_VOLVALUES(77,2,5)
end

T2if(SELECTVOL_PLACES_LIBRES
FROMT_VOLWHEREVOL_ID=2)>3
then
begin

T4UPDATET_VOL
SET
VOL_PLACES_LIBRES=

VOL_PLACES_LIBRES3
WHEREVOL_ID=2

T6if(SELECTVOL_PLACES_LIBRES
FROMT_VOLWHEREVOL_ID=2)<0

T8then
begin
UPDATET_VOL
SETVOL_PLACES_LIBRES=

VOL_PLACES_LIBRES+3
WHEREVOL_ID=2
return
end

T10INSERTINTOT_CLIENT_VOLVALUES(88,2,3)
end

Hlasexecutedansuncontextedeconcurenceelledevienttoutaussiinacceptable!
VoicilecontenudestablespourlestempsT1T10pourlevol2etlesclients77et88:

Slectionnez
Temps T_VOL:
VOL_IDVOL_REFERENCEVOL_PLACES_LIBRES

T1

Slectionnez

Slectionnez
T_CLIENT_VOL:
CLI_IDVOL_IDVOL_PLACES_PRISES

2AF8126

T2

Slectionnez

2AF8126

T3

Slectionnez

2AF8121

T4

Slectionnez

2AF8122

T5

Slectionnez

2AF8122

T6

Slectionnez

2AF8122

T7

Slectionnez

2AF8123

T8

Slectionnez

2AF8126

Nousn'avonstoujourspasrsolunotreproblme.Caraucunclientn'atservit!C'estencorepire,vousallezentranerlafaillitedevotre
compagnieencontinuantcommea!
Enfait,seulunetransactionpeutpermettredenoussauverdel'embarras.

1.2.Pourquoipasdesverrous?
Alorscertainsdirons,"maisilsuffitdeposerunverrousurlatable...oulaligne...".
D'accord,saufquecelan'existepasenSQLetquelesverroussontdesmcanismesinternesenprincipeinaccessibles.Leverrouestenfait

http://sqlpro.developpez.com/cours/sqlaz/techniques/

3/24

16/2/2015

LespetitspapiersdeSQLproTechniquesdesSGBDR
l'undesmoyensd'assurerlaconcurrenceentrelesutilisateursmaisseseffets,danslecadred'uneutilisationdirectepeuventtreplus
perversquel'utilisationdestransactions.
Eneffetquin'ajamaisentenduparldu"verroumortel,"dealock"enanglais,aussiapelltreintefatale.
L'utilisationdeverrous,mmesielleestpermiseparleSGBDRestproscriretotalementsansunematriseparfaitedesphnomnesde
concurrencequisupposed'avoirfaitundiagramneduparalllismedestchesafindedbusquerlespointsdeconcurrencesujetblocage.
Celac'taitl'informatiquedegrandpapal'aidedefichiersquel'onouvraitenmodeexclusifpoureffectuersesmodificationsenCOBOL...
EncorefautilsavoirquelstypesdeverroussontdisponiblessurleSGBDR:optimistes,pessimistes,exclusifs,partags,detable,depage,de
lignedecolonne??????????
Enrevanche,voicicommentceproblmeestrsoluparunegestiondetransaction:

Slectionnez
BEGINTRANSACTIONPLACE_AVION
UPDATET_VOL
SETVOL_PLACES_LIBRES=VOL_PLACES_LIBRES5
WHEREVOL_ID=2
INSERTINTOT_CLIENT_VOLVALUES(77,2,5)
if(SELECTVOL_PLACES_LIBRES
FROMT_VOLWHEREVOL_ID=2)<0
then
ROLLBACKTRANSACTIONPLACE_AVION
else
COMMITTRANSACTIONPLACE_AVION

tudionsleseffetsdececodeenconcurrence:

Slectionnez

Slectionnez
T1BEGINTRANSACTIONPLACE_AVION1
T3UPDATET_VOL
SETVOL_PLACES_LIBRES=VOL_PLACES_LIBRES5
WHEREVOL_ID=2
T4INSERTINTOT_CLIENT_VOLVALUES(77,2,5)
T5if(SELECTVOL_PLACES_LIBRES
FROMT_VOLWHEREVOL_ID=2)<0
T6then
ROLLBACKTRANSACTIONPLACE_AVION1
T7else
COMMITTRANSACTIONPLACE_AVION1

T2BEGINTRANSACTIONPLACE_AVION2
latransactionattendlalibration
desressourcesdel'autretransaction

T8UPDATET_VOL
SETVOL_PLACES_LIBRES=VOL_PLACES_LIBRES3
WHEREVOL_ID=2
T9INSERTINTOT_CLIENT_VOLVALUES(88,2,3)
T10if(SELECTVOL_PLACES_LIBRES
FROMT_VOLWHEREVOL_ID=2)<0
T11then
ROLLBACKTRANSACTIONPLACE_AVION2
T12else
COMMITTRANSACTIONPLACE_AVION2

Commenousallonslevoir,toutbienfonctionn:

Slectionnez
Temps T_VOL:
VOL_IDVOL_REFERENCEVOL_PLACES_LIBRES

T1

Slectionnez

Slectionnez
T_CLIENT_VOL:
CLI_IDVOL_IDVOL_PLACES_PRISES

2AF8126

T2

Slectionnez

2AF8126

T3

Slectionnez

2AF8121

T4

T5

T7

Slectionnez

Slectionnez

2AF8121

7725

Slectionnez

Slectionnez

2AF8121

7725

Slectionnez

Slectionnez

2AF8121

7725

http://sqlpro.developpez.com/cours/sqlaz/techniques/

4/24

16/2/2015

LespetitspapiersdeSQLproTechniquesdesSGBDR

T8

Slectionnez

Slectionnez
2AF8122

T9

7725
8823

Slectionnez

Slectionnez
2AF8122

T10

T11

7725
8823

Slectionnez

Slectionnez
2AF8122

7725
8823

Slectionnez

Slectionnez

2AF8121

7725

T6n'estpasexcutcommeT12,l'utilisateur1voitsatransactionvalideetle2lavoitannule.C'estdirequelecontenudestablesrevient
auxmmedonnesqu'ilyavaitaudbutdelatransactionT2.

1.3.Commentpiloterunetransaction?
Nousvenonsdevoircommentdmarrerunetransactionetcommentlavalideroul'annuler.Ilfauttoujoursqu'unetransactionpossdeune
ordreCOMMITouROLLBACK,sansquoielleperdurejusqu'plussoif...enprincipejusqu'cequel'utilisateursedconnecte.
ATTENTION:lanormeprvoitquetouteconnexionunSGBDRentameunetransaction.C'estvraisurcertainsserveurs,fauxsurd'autres
commeSQLServerquitravaillentenAUTOCOMMIT,c'estdirequechaqueordreSQLconstitueunetransactionensoi,immdiatementauto
valideouautoannule.Danscecasilfautobligatoirementcommencerunetransactionparl'ordreSQLBEGINTRANSACTION.
Leserveurfaitdel'AUTOCOMMIT(horsnormeSQL)

Slectionnez
BEGINTRANSACTION[nom_transaction]
...
ROLLBACK|COMMITTRANSACTION[nom_transaction]
...
COMMIT|ROLLBACKTRANSACTION[nom_transaction]

LeServeurnefaitpasd'AUTOCOMMIT(normeSQL)

Slectionnez
...
COMMIT|ROLLBACK
...
ROLLBACK|COMMIT

Parlonsmaintenantduniveaud'isolation,lafameuse"permabilit"dontjevousaisparlaudbut.C'estunconceptunpeudifficile
retenircarildoits'apprcieruniquementenpensantdeuxtransactionss'excutantenconcurrence.N'oublionspasqueleSGBDRcompte
tenudesvolumesdedonnestraiterdoitpouvoirservirtoutunchacunaveclammechanced'accsauserveuretdonclesprocessussont
parallliss.
Nouspourrionscomparerl'isolationd'unetransactionlapermabilitd'untuyau.Parexempledeuxrobinets(l'undevinrouge,l'autrede
blanc)situsctectepeuventtredotsensortie:
d'aucuntuyau(d'oudesclaboussuresetlemlangedesliquidespourfaireduros!)
d'untuyauentissuquis'humidifie,etpeutpolluerl'autreliquidesiilentreencontact
d'untuyauenverrequinouspermetdevoirlesliquidescouleretdoncd'ajusterledbit
ouenfind'untuyauenmtalopaquenepermettantnivisionnifuite...
Lepilotageduniveaud'isolationestassurparl'ordreSQL:

Slectionnez
SETTRANSACTIONISOLATIONLEVEL{READUNCOMMITED|READCOMMITED|REPEATABLEREAD|SERIALIZABLE}

1.4.Anomaliesdufaitdeprocessusconcurrents
Oulesanomalies"transactionnelles"...
Pourcomprendrel'utilitdecesdiffrentsniveaux,nousallonsnousintresserauxtroistypesd'anomaliespossiblesquipeuventsurvenirlors
del'excutionconcurrented'ordresSQL.
L'anomalielaplusgraveestlalectureimpropre(lecturesaleoudirtyread):elleseproduitlorsque'unetransactionlitdesdonnes
quin'ontpasencoretvalides.
Suit,l'anomaliedelecturenonrptable(nonrepeatableread):deuxlecturessuccessivedesmmesdonnesneproduisentpasle
mmersultatdanslammeligne.
Enfinlalecturefantme(phantomread)estuneanomaliequiseproduitlorsquedesdonnesnouvellesapparaissentoudisparaissent
dansdeslecturessuccessives.
Voiciunexempledelectureimpropre:l'utilisateur1ajoute10placesetannulesatransaction,tandisquel'utilisateur2veut7placessielles
sontdisponibles...

Slectionnez

Slectionnez

http://sqlpro.developpez.com/cours/sqlaz/techniques/

T2BEGINTRANSACTION2

5/24

16/2/2015

LespetitspapiersdeSQLproTechniquesdesSGBDR
T1BEGINTRANSACTION1
T3UPDATET_VOL
SETVOL_PLACES_LIBRES=VOL_PLACES_LIBRES+10
WHEREVOL_ID=2

T5ROLLBACKTRANSACTION1

T4if(SELECTVOL_PLACES_LIBRES
FROMT_VOLWHEREVOL_ID=2)>=7
then
T6begin
UPDATET_VOL
SETVOL_PLACES_LIBRES=VOL_PLACES_LIBRES7
WHEREVOL_ID=2
T7INSERTINTOT_CLIENT_VOLVALUES(77,2,5)
T8COMMITTRANSACTION
end
T9else
ROLLBACKTRANSACTION2

Etlesdonnesquisontmanipules:

Slectionnez
Temps T_VOL:
VOL_IDVOL_REFERENCEVOL_PLACES_LIBRES

T1

Slectionnez

Slectionnez
T_CLIENT_VOL:
CLI_IDVOL_IDVOL_PLACES_PRISES

2AF8126

T2

Slectionnez

2AF8126

T3

Slectionnez

2AF81216

T4

Slectionnez

2AF81216

T5

Slectionnez

2AF8126

T6

Slectionnez

2AF8121

T7

T8

Slectionnez

Slectionnez

2AF8121

7725

Slectionnez

Slectionnez

2AF8121

7725

Letempd'unupdateavort,latransaction2aludesinformationsqu'ellen'auraitjamaisdvoiretenatirlaconclusionqu'ellepouvait
servirlesplaces...Conclusionsurbooking!
Voicimaintenantunexempledelecturenonrptable:nousallonsconsidrerlecasounotreoprateurdsiretouteslesplacesd'unvolsi
ilyenplusde4...

Slectionnez

Slectionnez

T3BEGINTRANSACTION1
T4UPDATET_VOL
SETVOL_PLACES_LIBRES=VOL_PLACES_LIBRES4
WHEREVOL_ID=2
T5COMMITTRANSACTION1

http://sqlpro.developpez.com/cours/sqlaz/techniques/

T1BEGINTRANSACTION2
T2if(SELECTVOL_PLACES_LIBRES
FROMT_VOLWHEREVOL_ID=2)>=4
then

T6begin
UPDATET_VOL
SETVOL_PLACES_LIBRES=VOL_PLACES_LIBRES
(SELECTVOL_PLACES_LIBRES
FROMT_VOLWHEREVOL_ID=2)
WHEREVOL_ID=2
T7INSERTINTOT_CLIENT_VOLVALUES(77,2,
(SELECTVOL_PLACES_LIBRES
FROMT_VOLWHEREVOL_ID=2))
T8COMMITTRANSACTION
end
T9else

6/24

16/2/2015

LespetitspapiersdeSQLproTechniquesdesSGBDR
ROLLBACKTRANSACTION2

Etlesdonnesquisontmanipules:

Slectionnez
Temps T_VOL:
VOL_IDVOL_REFERENCEVOL_PLACES_LIBRES

T1

Slectionnez

Slectionnez
T_CLIENT_VOL:
CLI_IDVOL_IDVOL_PLACES_PRISES

2AF8126

T2

Slectionnez

2AF8126

T3

Slectionnez

2AF81216

T4

Slectionnez

2AF8122

T5

Slectionnez

2AF8122

T6

Slectionnez

2AF8120

T7

T8

Slectionnez

Slectionnez

2AF8120

7722

Slectionnez

Slectionnez

2AF8120

7722

Notreutilisateur2voulaitaumoins4placesetenreu2...Conclusion,vousavezperduunclient!
Derniercas,lalecturefantme:notreutilisateur2,dsiren'importequelvolpascherpouremmenersonquipedefoot(soit11personnes)
unedestinationquelconque.

Slectionnez

Slectionnez
T3BEGINTRANSACTION1
T4INSERTINTOT_VOL
VALUES(5,'AF111',125)
T5COMMITTRANSACTION1

T1BEGINTRANSACTION2
T2ifEXISTS(SELECT*
FROMT_VOL
WHEREVOL_PLACE_LIBRE>=11)then

T6begin
UPDATET_VOL
SETVOL_PLACES_LIBRES=VOL_PLACES_LIBRES11
WHEREVOL_PLACES_LIBRES>=11
T7INSERTINTOT_CLIENT_VOLVALUES(77,4,11)
T8COMMITTRANSACTION
end
T9else
ROLLBACKTRANSACTION2

Etlesdonnesquisontmanipules:

Slectionnez
Temps T_VOL:
VOL_IDVOL_REFERENCEVOL_PLACES_LIBRES

T1

Slectionnez

Slectionnez
T_CLIENT_VOL:
CLI_IDVOL_IDVOL_PLACES_PRISES

4AF325258

http://sqlpro.developpez.com/cours/sqlaz/techniques/

7/24

16/2/2015

LespetitspapiersdeSQLproTechniquesdesSGBDR

T2

Slectionnez

4AF325258

T3

Slectionnez

4AF325258

Slectionnez
T4

4AF325258
5AF111125

Slectionnez
T5

4AF325258
5AF111125

Slectionnez
T6

4AF325247
5AF111114

Slectionnez

Slectionnez

T7
4
AF325247
5AF111114

77411

Slectionnez

Slectionnez

T8
4AF325247
5AF111114

77211

11placesonttvolatilisduvolAF111etc'estcommecelaqu'uncertaint,desavionsd'AirFrancevolaientvideavectouteslesplaces
rserves!!!

1.5.Niveaud'isolationdestransactionsetanomaliestransactionnelles
C'estpourseprserverdetellesanomaliesquelanormeSQL2misenplaceleniveaud'isolationdestransactions.
Letableaucidessousrsumelesdiffrentsniveauxd'isolationpraticablesetlesanomaliesqu'elledoiventimprativementviter:

Anomalie

READUNCOMMITED
(niveau0)possibilitdelire
desinformationsquisonten
coursd'insertionmaisnon
valides

READCOMMITED
(niveau1)Desdonnes
peuventtremodifies
avantlafindela
transaction

REPEATABLEREAD
(niveau2)Denouvelles
lignespeuventapparatre
avantlafindela
transaction

SERIALIZABLE(niveau3)
lestransactionssontplaces
ensrieouleSGBDRfait
"commeci"

Lectureimpropre

possible

impossible

impossible

impossible

Lecturenonrptable

possible

possible

impossible

impossible

Lecturefantme

possible

possible

possible

impossible

Enprincipe,lanormefixeleniveaud'isolationpardfautduSGBDRSERIALIZABLE!
Enpratique,c'estrarementlecas...ParexempleSQLServerdeMicrosoftfonctionnepardfaut,auniveaud'isolation1(READCOMMITED)ce
quiexpliquesarelativegranderapiditmaisdepossiblesanomaliestransactionnellessil'onyprendpasgarde.
Maismedirez,vous...PourquoiaccepterdedescendreendessousduniveauSERIALIZABLE?
Simplementparcequeceniveaulepluscontraignantentraneunepnalisationcertaineduserveurentermedeperformance!Or,nous
n'avonspastoujoursbesoindeceniveaud'extrmeisolation...LanormeSQLlaisselechoixdepiloterlestransactionscommeledveloppeur
leveut,conditionqu'ilaitcechoixetqu'ilenmesuretouteslesconsquences...Encettematirehlas,nombrededveloppeurslaissent
faireleserversansseposerlesbonnesquestions....
Ilestconseilldesesitueraumoinsauniveaucorrespondantauxutilisationssuivantes:
UPDATEavecmisejourdeclef(primaireoutrangres),INSERT:SERIALIZABLE
UPDATEsurvaleurscourantes,DELETEfiltrssurCLEFS:REPEATABLEREAD
SELECTintgres,DELETEsansfiltre:READCOMMITED
SELECTnonintgres:READUNCOMMITED

1.6.Conclusion
Vousavezcomprisquedsquedesmisesjourinterviennentenconcurrenceilpeutsurvenirdesanomaliestransactionnelles,cequi,dansce
cas,faitperdrelabasel'intgritdesesdonnes...
Ilestdoncimpossibledesepasserdelalogiquetransactionnelle,saufdfinirunseulutilisateurmmed'effectuertoutesles
misesjour(INSERT,UPDATE,DELETE)cequicantonnelesbasesdedonnesquiensontdpourvuesdesutilisationsdugenre"basede
donnesdocumentaires"oul'essentieldel'activitduserveurconstituedelalecturededonnes.

1.7.Oplacerlestransactions?Surleserveurousurleclient?
OUI,mais...onpeutgrerdestransactionssoitdansdesprocduresstockesauseinduserveur,soitdansducodeclient...Qu'estcequiest

http://sqlpro.developpez.com/cours/sqlaz/techniques/

8/24

16/2/2015

LespetitspapiersdeSQLproTechniquesdesSGBDR
prfrable?
L'idedemanipulerdestransactionsdepuisuncodeclient(VB,Delphi,Java,C++...)estsduisantemais"cassegueule"etpeutentranerle
piredupire:unblocagetotalduserveur.Eneffetdsquel'onentameunetransaction,leSGBDRposelesverrousadquatssurles
ressourcesvisesparlaprocdure.SileclientperdlamainsursoncodeetneprovoquejamaisdeCOMMITouROLLBACK,lesressourcesne
sontpaslibresetentranentl'impossibilitpourlesautresutilisateursd'accderauxdonnesvrouilles.C'estpourquoiunelogique
transactionnelledoittoujourstreexcuteauplusprsduserveuretnonsurleposteclient,moinsquevousayezprvuel'artillerielourde
:postesuronduleuronlineourseaulectriquesuralimentationsecourue,OShyperstable,antivirus,etc...
Deplus,ilconvientquelaprocdurenesoitjamaisenattented'unemanipulationdel'utilisateur(commeunedemandedesaisieoude
confirmation)cartouteattentebloquelesressourcesuncertaintempsetmetenattented'autresutilisateurs.C'estalorslechteaudecarte,
chaqueutilisateurattendqu'unautrelibrelesressourcesetcelapeutentranerleblocagetotalduSGBDR,parexempleunverroumortel...
C'estpourquoionveilleraplacerlestransactions,soitdansuneprocdurestocke(l'idalentermedescuritetd'intgrit)soitdansdes
objetsmtiersappelsparuneserveurd'applicationoud'objetaussibienscurisqueleserveurSGBDRetdansunrseauconnectiquement
proche.

1.8.Qu'estcequele"verroumortel"?
Cephnomneseproduitlorsquedeux(ouplus)utilisateursveulentaccderauxmmesressourcesmaisdansunesquencedetemps
inverse.NousavonsditqueleSGBDRposaitdesverrousadquatssurlesressourcesparrapportauxobjetsconcernsparlestransactions.Le
typedeverroudpendd'ailleursdel'ordreSQLexcutetduniveaud'isolationdemand.Certainstraitementsncessitelaposesimultande
plusieursverroussurdestablesdiffrentes.Leverroumortels'appelledanslalittratureinformatique"deadlock"enanglais,etencore
treintefataleouinterblocageenfranais.
Regardonscequisepassedansdeuxtransactionssujettesuntelverroumortel...
L'utilisateur1veutprendre3placesd'avionsurlevolAF714,tandisquel'utilisateur2,quivientd'trehospitalisveutrestituer5placessur
cemmevol...

Slectionnez
T1BEGINTRANSACTION1
T3UPDATET_VOL
SETVOL_PLACES_LIBRES=VOL_PLACES_LIBRES3
WHEREVOL_ID=1

T5INSERTINTOT_CLIENT_VOLVALUES(77,1,3)

T7COMMIT

Slectionnez

T2BEGINTRANSACTION2

T4DELETEFROMT_CLIENT_VOL
WHERECLI_ID=88
ANDVOL_ID=1
T6UPDATET_VOL
SETVOL_PLACES_LIBRES=VOL_PLACES_LIBRES+5
WHEREVOL_ID=1
T8COMMIT

Voyonscequisepassedansledtail,enmatiredeverrous,lorsdudroulementconcurrentdecesdeuxtransactions:

Slectionnez

Slectionnez

BEGINTRANSACTION1

LatransactionT1dmarrenormalement

Slectionnez

Slectionnez

BEGINTRANSACTION2

LatransactionT2dmarrenormalement

Slectionnez

Slectionnez

T1

T2

T3 UPDATET_VOL

SETVOL_PLACES_LIBRES=VOL_PLACES_LIBRES3
WHEREVOL_ID=1

T4

Slectionnez

Slectionnez

DELETEFROMT_CLIENT_VOL
WHERECLI_ID=88
ANDVOL_ID=1

AVANTd'excuterlarequte,leSGBDRpose
unverrousurlatableT_CLIENT_VOLpour
l'utilisateur2

Slectionnez
T5
INSERTINTOT_CLIENT_VOLVALUES(77,1,3)

Slectionnez
T6

AVANTd'excuterlarequte,leSGBDRpose
unverrousurlatableT_VOLpourl'utilisateur1

UPDATET_VOL
SETVOL_PLACES_LIBRES=VOL_PLACES_LIBRES+5
WHEREVOL_ID=1

Slectionnez
LeSGBDRtented'obtenirunverrousurlatable
T_CLIENT_VOLpourl'utilisateurT1maisillui
estmomentanmentrefusparcequelatableest
vrouilleparT2

Slectionnez
LeSGBDRtented'obtenirunverrousurlatable
T_VOLpourl'utilisateurT2maisillui
estmomentanmentrefusparcequelatableest
vrouilleparT1

Acestadelesdeuxtransactionssontenattentedelibrationderessources.Aucunenevaseterminercarchacuned'elleattendquel'autre
librelaressourcedontellebesoin.C'estl'interblocage,l'treintefatale,leverrroumorteloudeadlock.

1.9.Maisalors?Lestransactionspeuventinduireunblocage???
http://sqlpro.developpez.com/cours/sqlaz/techniques/

9/24

16/2/2015

LespetitspapiersdeSQLproTechniquesdesSGBDR
Ouietnon.CeladpendduSGBDRetduniveaud'isolation.CertainsSGBDRcommeOracleouInterBasesontdotsd'unalgorithmequi
empchetoutinterblocage.Cetalgorithmepeuttreun"timeout",quituemomentanmentunprocessusauhasardlorsqueplusieurs
processussontbloqus.Bienentendu,leniveaud'isolationjoueaussibeaucoupsurcephnomne.Unniveausrializableindiqueauserveur
deplacerlestransactionsensrie(oudefairecommeci).Celapeutgarantirqu'iln'yaitpasd'interblocage,maispnaliseleserveurpuisqu'il
devientimpossibledeparallliserlesprocessus.Uneautreastuceestdetoujoursmanipulerlestables,dansvosprocduresstockes,comme
dansvotrecodeclient,danslemmeordre(parexemplel'ordrealphabtiquedunomdetable)...
NotezquecertainsGSBDR,commeMSSQLServersontassezsujetl'interblocageetleseulremdeestengnralde"tuer"unutilisateur
(enfin,saconnexion!).
2.AquoisertL'intgritrfrentielle?

L'intgritrfrentiellesertempcherqu'uneligned'unetablequirfrenceuneligned'uneautretablevoitlelienlogiqueentrelesdeux
lignesbrise.Queseraitunefacturesileclientvenaittreeffacdelatabledesclients?

Ici,lescommandes6et7fontrfrencesauxclient4et9quin'existentpasdanslatableT_CLIENT...

2.1.Lemcanisme
Lemcanismed'intgritrfrentielledoitpermettred'assurer:
quetoutclientrfrencparuneautretablenesoitpassupprim,oualors
quel'onsupprimeaussitoutesleslignesfillesdestablesquirfrenceleclientsupprim
quelarfrenceduclient,sielleestmodifi,soitrpercutedanstoutesleslignesdestablesfillesquilarfrence,oualors
quetoutemodificationdecetterfrencesoitinterditesideslignesdetablesfillesl'utilise
LanormeSQL2prvulesmodesdegestiondesintgritsrfrentiellessuivants:

Slectionnez

Slectionnez

ONDELETE{NOACTION|CASCADE}

ONUPDATE{NOACTION|CASCADE}

Quisignifieque:

Slectionnez
ONDELETENOACTION

Slectionnez
ONDELETECASCADE

Slectionnez
ONUPDATENOACTION

Slectionnez
ONUPDATECASCADE

Siunesupressionintervientalorsqueleclientest
rfrencparunecommande,lasuppressionest
avorte

Siunesupressionintervientalorsqueleclientest
rfrencparunecommande,laoules
commandesrfrencespourceclientsontaussi
supprimes

Siunemiseajourdelaclefduclientintervient
alorsquececlientestrfrencparune
commande,lamodificationestavorte
Siunemiseajourdelaclefduclientintervient
alorsquececlientestrfrencparune
commande,laoulescommandesrfrencepour
ceclientvoitleurcleftrangreprendrela
nouvellevaleur

Bienentenduonpeutparfaitementsupprimerunclientquinepossdepasdecommandeoumodifierlavaleurdesaclefmmelorsquele
modeNOACTIONestactif.
Danstouslescas,lemodeNOACTIONestprfrer.EneffetlemodeCASCADEpeutentraneruneavalanchedesuppressionsoudemise
jourduplusmauvaiseffetsurlesperformancesduSGBDR!
Cemcanismesimpleetrobusteestcompltpard'autrespossibilitsqu'offrelanormeSQLetquisont:SETDEFAULTetSETNULL.

Slectionnez
ONDELETESETDEFAULT

http://sqlpro.developpez.com/cours/sqlaz/techniques/

Siunesupressionintervientalorsqueleclientest
rfrencparunecommande,leslignesdestables
fillesrfrencesparceclientvoitlavaleurdela
clefpasserlavaleurpardfautdfinielorsdela
crationdelatable.
Siunesupressionintervientalorsqueleclientest

10/24

16/2/2015

LespetitspapiersdeSQLproTechniquesdesSGBDR
Slectionnez
ONDELETESETNULL

Slectionnez
ONUPDATESETDEFAULT

Slectionnez
ONUPDATESETNULL

rfrencparunecommande,laoules
commandesrfrencespourceclientvoitla
valeurdelacleftrangrepasserNULL.
Siunemiseajourdelaclefduclientintervient
alorsquececlientestrfrencparune
commande,leslignesdestablesfillesrfrences
parceclientvoitlavaleurdelaclefpasserla
valeurpardfautdfinielorsdelacrationdela
table.
Siunemiseajourdelaclefduclientintervient
alorsquececlientestrfrencparune
commande,laoulescommandesrfrencespour
ceclientvoitlavaleurdelacleftrangrepasser
NULL.

Cesdeuxnouvellesrglesproposentunealternativeafindegrerdemanireintelligenteunepseudocascade...
Quelintrtmedirezvousd'avoirdescommandesdontlarfrenceduclientestNULLoubien0(unclientgnriquedontl'existence
physiqueestfausse,parexemplemoimme...)?
L'intrtestsimple:pouvoirfairelemnagedanslestablesdemanireultrieure...Parexempleonpourraprvoirdesupprimertoutesles
commandesdontlarfrenceclientestNULLou0lanuit,lorsqueletrafficduserveuresttrsfaibledansunbatchplanifidclench
automatiquement.Bienentendu,danscecasilfautfaireattentionnepascomptabiliserdanslesrequtesleslignesdontlarfrencedu
clientestNULLou0.Ainsiuncumuldumontantdescommandespourconnatrelechiffred'affairegnrmensuellementnedoitpasprendre
encompteleslignesavecunerfrencedeclient0ouNULL...
TouslesSGBDRnesontpasaussiperformantquelanormel'imposeenmatiredegestiondel'intgritrfrentielle.Eneffet,certains
commeORACLEouInterBaseonimplmentlaplupartdecesrglesdegestion.D'autrescommeMSSQLServerneproposentqueleNO
ACTION.Danscederniercas,l'utilisationdetriggerspermetdesimulerlesautresrgles.

2.2.L'intgritrfrentielle,fondementdesSGBDR...
Lagestiondel'intgritrfrentielleestdeloinlepointleplusimportantpourdcidersiunSGBDestrelationnelounon.Dpourvudece
mcanismeilagitcommeaubonvieuxtempsdesfichiersCOBOL.Munidecemcanismeilagitenresponsabledel'intgritdesdonnes.
AutrementditunSGBDquin'estpasdotd'unemcanismedegestiondesintgritsrfrentiellesnemritetoutsimplement
paslenomdesystmedegestiondebasesdedonnes"relationnelles".
C'estmalheureusementlecasdeMySQL,quireprsenteunergressioncertaineparrapportdessystmesdefichiersplatscommeParadox
quilapossde!

2.3.Peutonsepasserdel'intgritrfrentielle?
Danslaralitc'estimpossible!Latentationdenepasutiliserl'intgritrfrentielle(oud'avoirunSGBDquinelesupportepas)etfaire
celadansducodeclientestsduisante...Maiscassegueule:l'idephalacieusequiconsistedire,jesupprimed'abordlesfacturesensuite
lesclients,estinacceptablesiellen'estpasconduitedansunetransaction.Eneffetrienn'empchelecodeclientdes'arrter(pannedisque,
coupuredecourant,rseauHS,pausecaf...)entrelesdeuxrequtescequisupprimelescommandessansavoirpusupprimerleclient...
Aliresurlesujet:
Lagestiondel'intgritrfrentielle
Mais,lisezlasuite,caronpeuteffectivementsepasserdel'intgritrfrentielleconditionquelabasededonnessupportelestriggers...
3.Aquoiserventlesdclencheurs(Triggers)?

S'ilavait2chosesretenirpourconstituerunSGBDRausensrelationnelduterme,seseraitlestransactionsetlestriggers.Aveccesdeux
outils,onpeutaismentcrertouslesmcanismesd'intgritrfrentiellequel'onsouhaiteetassureruneparfaiteintgritdesdonnes.
C'estd'ailleurspourcelaquelanormeSQL3aimposl'utilisationdestriggers.

3.1.C'estquoiuntrigger?
Letermefranaisest"dclencheur".Untriggerestdoncunlmentdecodequisedclenchesurunvnementprcis,serapportantun
objetdelabasededonnes.C'estexactementlemmeconceptquelaprogrammationvnementielledanslecadred'interfacesgraphiques.
Jeneseraisd'ailleurspastonnquelesOnClicketautreOnMouseDownn'aienttinspirsparlanotiondetriggersdesSGBDR,carilne
fautpasoublierquelesSGBDRexistaientbienavantlespremierslangagesfaisantrfrencedesvnementsgraphiques.Maiscecin'estpas
ledbat.
AusensdelanormeSQL3,untriggersedfinituniquementsurlesobjetsdetypeTABLE,concernelesvnementssuivants:INSERT,
UPDATE,DELETEetpeuttredclenchBEFORE(c'estdireavantsurvenancedel'vnement)ouAFTER(c'estdireaprssurvenancede
l'vnement).
LagrandediffrenceentrelecodevnementielgraphiquedeslangagescommeDelphiouVisualBasic,c'estquel'onpeutplacerducode,
avantouaprslesurvenancedel'vnement,alorsquedansleslangagesgraphiques,ceparamtren'existepas(enfin,j'allaisoublier
l'extraordinairelangageObjectPaldeParadoxquiproposaitnonseulementlepilotageavantaprsdanslemmecode,maisencorele
"bouillonnement"del'venement,c'estdiresaremontedepuisleplusgrandconteneurjusqu'l'objetcible!aucasouvousl'aurez
oubli,celuiquiacrObjectPalensuitecrDelphipuisC#maintenantchezMicrosoft!!!).
LasyntaxenormativeSQL3d'untriggerestlasuivante:

Slectionnez
CREATETRIGGERnom_trigger
{BEFORE|AFTER}{INSERT|UPDATE|DELETE}
ONnom_table
code

Elleestplusconsquentedanssontendue,maisseulecettepartienousintressecarelleensynthtisetouteslespossibilits.
Lachoselaplusattractivedansuntrigger,sontlespseudotablesOLDetNEWquicontiennentlesdonnesencoursd'insertion,demisejour
oudesuppression...

3.2.Commentamarche?
Examinonscequisepassedansuncasconcret.

http://sqlpro.developpez.com/cours/sqlaz/techniques/

11/24

16/2/2015

LespetitspapiersdeSQLproTechniquesdesSGBDR
Soitlestables:

Slectionnez

Slectionnez

CREATETABLET_CLIENT
(CLI_IDINTEGERNOTNULLPRIMARYKEY,
CLI_NOMCHAR(32)NOTNULL,
CLI_PRENOMVARCHAR(32),
CLI_STATUTCHAR(1))

INSERTINTOT_CLIENTVALUES(1,'DUPONT','Marcel','C')
INSERTINTOT_CLIENTVALUES(4,'DUFOUR','Martin','C')
INSERTINTOT_CLIENTVALUES(17,'DUHAMEL','Manuel','C')
INSERTINTOT_CLIENTVALUES(161,'DUBOIS','Marie','C')

Slectionnez

Slectionnez

CREATETABLET_PROSPECT
(PRP_IDINTEGERNOTNULLPRIMARYKEY,
PRP_NOMCHAR(32)NOTNULL,
PRP_PRENOMVARCHAR(32))

INSERTINTOT_PROSPECTVALUES(14,'Laporte','Eric')
INSERTINTOT_PROSPECTVALUES(17,'Lambert','Ernest')
INSERTINTOT_PROSPECTVALUES(161,'Laurent','Emeric')
INSERTINTOT_PROSPECTVALUES(4874,'Lautier','Etienne')

NotreutilisateurveutfairepassertoutlesprospectsdanslatableT_CLIENTaveclestatut'P'.Oui,mais,aupassageilveutleurdonnerune
clefcomptatibleavecleCLI_IDetreformaterlenomenmajuscule...
Orunsimpleordred'insertionbasiqueduSQLvaviolerlacontrainted'unicitdelaclefetrejetterenblocl'insertion...

Slectionnez

Slectionnez

INSERTINTOT_CLIENT
SELECTPRP_ID,PRP_NOM,PRP_PRENOM,'P'
FROMT_PROSPECT

ViolationdelacontraintePRIMARYKEY'PK__T_CLIENT__251C81ED'.
Impossibled'insreruneclendoubledansl'objet'T_CLIENT'.
L'instructionatarrte.

Maisnouspouvonspallierceproblme,sansrientoucherdenotreordred'insertionenajoutantuntriggerquivarectifierlesdonnesen
coursd'insertionAVANTqu'ellenesoientrellementdposesdanslatable:

Slectionnez
CREATETRIGGERTRG_INS_BEF_CLIENT
BEFOREINSERT
ONT_CLIENT
UPDATENEW/*cettepseudotablecontientlesprospectsavantleurinsertion!*/
SETPRP_ID=PRP_ID+(SELECTMAX(CLI_ID)FROMT_CLIENT),
PRP_NOM=UPPER(PRP_NOM)
/*onmodifielesdonnesdelapseudotableavantdelesinsrerdfinitivement*/

Dslorsnotreinsertionvabiensepasser:

Slectionnez
INSERTINTOT_CLIENT
SELECTPRP_ID,PRP_NOM,PRP_PRENOM,'P'
FROMT_PROSPECT

Slectionnez
(4)lignesajoutes

Pourconfirmationdecequis'estpass,nouspouvonsrelirelatableclient:

Slectionnez

Slectionnez
SELECT*
FROMT_CLIENT

CLI_IDCLI_NOMCLI_PRENOM

1DUPONTMarcel
4DUFOURMartin
17DUHAMELManuel
161DUBOISMarie
175LAPORTEEric
178LAMBERTErnest
322LAURENTEmeric
5035LAUTIEREtienne

3.3.Aquoiasert?
Mais,medirezvous,celanousaurionspulefairedirectementdansl'ordred'insertion...Parexempleaveclarequtesuivante:

Slectionnez
INSERTINTOT_CLIENT
SELECTPRP_ID+(SELECTMAX(CLI_ID)FROMT_CLIENT),UPPER(PRP_NOM),PRP_PRENOM,'P'
FROMT_PROSPECT

C'esttoutfaitvrai,maissivousaviezdesdonnesprovenantdetoutesautrestables,alorsilauraitfallutadpatervotrecodeetlemodifier
pourchaquecas,alorsquedanslecasd'untrigger,cecodeestgnriquequelquesoitl'insertionquevousvoulezfaireetd'oqu'elle
provienne!
Lescasd'utilisationdestriggerssontassezlarge:
leformattagededonnes
l'autoincrmentationdeclefs
lasuppressionencascade
l'abandond'unesuppressionsielleentranedeslignesorphelines
etplusgnralementletraitementsd'associationsprovenantsdemodlescomplexescomme

http://sqlpro.developpez.com/cours/sqlaz/techniques/

12/24

16/2/2015

LespetitspapiersdeSQLproTechniquesdesSGBDR
lesrelations1:nounestunelimitefixe(parexemple3)
lesantirelations(parexemplelesmotsnoirs,voirIndexationtextuelle)
lesmodleshritage(parexempleuneentitgnriqueVEHICULEetdesentitsspcialisescommeVOITURE,AVIONetBATEAU...)
lesarbresmodlissparintervalles(voirGestiond'arbresparreprsentationintervallaire)
...
Essayezdoncdemodliserunerelationdanslaquellelelienentretablemreettablefillenedoitpasdpasserunmaximumde3
occurrences...Parexempleleprtdelivresdansunebibliothquemunicipale?
Dansuntelcas,pourempcheruneinsertionsurnumraire,ilsuffitdecompterleslignesdjinsres,etdsquelenombredeligne
dpasse3,alorsl'invocationd'unordreROLLBACKempchelapseudotableNEWd'attendrelatablecible.Lesdonnessurnumrairesnesont
alorspasinsres.
Voicil'exempled'unteltrigger:

Slectionnez
CREATETRIGGERTRG_INS_BEF_PRET
BEFOREINSERT
ONT_CLIENT
FOREACHROW
IFEXISTS(SELECT1
FROMT_PRETP
JOINNEWN
ONP.EMPRUNTEUR_ID=N.EMPRUNTEUR_ID
HAVINGCOUNT(*)=3)
THEN
ROLLBACK

Quefaitondanscecode?D'abordnotezl'expressionFOREACHROW,quisignifiequeledclencheurvas'activerautantdefoisqu'ilyade
lignedanslatableNEW,ensubstituantlatableNEWetsesnlignesenndclenchementsd'unetableNEWnecontenantqu'uneseuleligne.
Ensuitenotezquel'onlielatableNEWlatabledespretssurl'identifiantdel'emprunteur.Puisoncomptelenombredelignesdecette
jointureetoninvoqueunROLLBACKsicecomptageestgaltois,afindenepasrajouterdenouvelleslignesd'emprunts.
Simplenon?Ettellementlgant!

3.4.Peutons'enpasser?Faireautrement?
Sil'onn'utilisepasdemodlescomplexesetquel'intgritrfrentielleestenplace,alorsilestparfaitementpossibledesepasserdes
triggers.Maisvuleursouplesse,lascuritqu'ilsapportent,etlaconcisionducodequ'ilsoffrent,ilseraitfoliedes'enpriver!
4.Aquoiserventlessousrequtes?

Certainscommentairesd'utilisateursindiquentrgulirementdansleursmailsqu'ilsuffitdefairedesjointurespourremplacertoutesous
requte.IlestbienvidentquelecommitdenormalisationduSQLcomposdemembresminentscommeChrisDATE,neseseraitpas
vertulesfaireexisterauseindelanormesiellesservaitrien!

4.1.C'estquoiunesousrequte?
Unesousrequteestunerequtesitul'intrieurd'uneautrerequte.Laplupartdutempsils'agitd'ordresSELECTimbriqus.
Pouruncourssurlesujet,voir:
lessousrequtes

4.2.Peutons'enpasser,faireautrement?
Unsimpleexemple,donnparPeterGULUTZANmontrequ'ilestimpossibledes'enpasser:
Soitlatable:

Slectionnez
CREATETABLETAB1(COL1INT)
CREATETABLETAB2(COL2INT)

Slectionnez
INSERTINTOTAB1VALUES(1)
INSERTINTOTAB1VALUES(1)
INSERTINTOTAB1VALUES(2)
INSERTINTOTAB2VALUES(1)
INSERTINTOTAB2VALUES(2)
INSERTINTOTAB2VALUES(2)

Tentezdoncdereproduirelarequtesidessousetsonrsultatsanssousrequte...

Slectionnez
SELECTTAB1.COL1ASCOL
FROMTAB1
WHERETAB1.COL1IN(SELECTTAB2.COL2
FROMTAB2)

Slectionnez
COL

1
1
2

Bienentendudans80%desrequtesquejevoitpasserdevantmesyeux,ilestpossibledetransformerlasousrequteenjointurel'aidede
contorsionsassezdlicates.Maispour20%d'entreellesiln'yapasdesolution.TelestpasexemplelecasdesprdicatsMATCHetUNIQUE.
telestaussilecasdelaplupartdessousrequtesimplantesdanslaclausefrometcontenantunoprateurd'agrgatstatistique.
Lessousrequtesfacilitentlaviedudveloppeur,s'criventplusfacilementquedesjointuresdansbiendescas.Ellesontunrevers,ellesont
souventmoinsperformantesquedesjointures...

http://sqlpro.developpez.com/cours/sqlaz/techniques/

13/24

16/2/2015

LespetitspapiersdeSQLproTechniquesdesSGBDR
L'idephallacieusequiconsistedirequel'onpeuts'enpassersil'ondisposedetablestemporairesestfausse.Eneffet,entre
l'instanciationd'unetabletemporaireetlarequtesuivante,lesdonnespeuventchangeretfausserlersultat.Ilen
rsulteraitdeserreurs,moinsd'effectuersoncodedansunetransaction!
Eneffetilnefautpasoublierqu'unerequteestunetransactionimplicite...
C'estaussiassezdifficiledetraduireencodedessousrequtescorrles,cardanscecas,l'excutiondelasousrequteestrenouvelepour
chaquelignedelarequteprincipale...Letravaildevientvitecomplexeetletempsd'excutionsurleposteclientdevient
incommensurablementlong!
5.Aquoiserventlesoprationsensemblistes?

LesoprationsensemblistesduSQLsontlessuivantes:
l'union(UNION)
l'intersection(INTERSECT)
ladiffrence(EXCEPT)

5.1.Caressemblequoi?
SivousvoussouvenezdespatatesoudiagrammesdeVenn,alorsvouspouvezlesmatrialiserfacilement.
Danslecascontraire,vouspouvezlirecesujet:
Lesoprateursensemblistes

5.2.Estilpossibledes'enpasser?
Jevaisvoussurprendre...LarponseestindubitablementOUI!
L'intersection,commeladiffrencepeuventtreralisspardesconstructionsquivalentesbasedejointuresoudesousrequtes.Voir:
ConsidrationdiversessurlesoprationsensemblistesduSQL
Maisqu'enestilpourl'union?
Ilestpossibledelaraliserdeuxconditions:
queleSGBDRpossdeunefonctionoustructuredesubstitutiondesmarqueursNULL(COALESCE,CASE...ouquivalent)
queleSGBDRimplmenteleFULLOUTERJOIN
C'estassezrarequ'ilyaitcesdeuxlmentssansl'oprateurUNION.Deplus,lecotdecalculdecetquivalentestassezlevdufaitdela
prsencedesfonctionsdetransformation.
Voiciunecorrespondanceentreuneunionclassiquededeuxtables(lesdonnessontcellesdujeusuivant:
Ensembles_exemples):

Slectionnez

Slectionnez
SELECTOBJ_NOMASNOM,OBJ_PRIXASPRIX
FROMT_OBJET
UNION
SELECTMAC_NOMASNOM,MAC_PRIXASPRIX
FROMT_MACHINE
ORDERBYNOM,PRIX

Slectionnez
unionbasedejointureavecutilisationdeCOALESCE
SELECTCOALESCE(OBJ_NOM,MAC_NOM)ASNOM,
COALESCE(OBJ_PRIX,MAC_PRIX)ASPRIX
FROMT_OBJETO
FULLOUTERJOINT_MACHINEM
ONO.OBJ_NOM=M.MAC_NOM
ANDO.OBJ_PRIX=M.MAC_PRIX
ORDERBYNOM,PRIX

NOMPRIX

ASSIETTE26.5
AVIONNULL
LIVRE128.0
MOTO43528.0
PERCEUSE259.98999
PERCEUSE260.0
RVEIL128.0
TABLE5600.0
VENTILATEUR250.0

Slectionnez
NOMPRIX

ASSIETTE26.5
AVIONNULL
LIVRE128.0
MOTO43528.0
PERCEUSE259.98999
PERCEUSE260.0
RVEIL128.0
TABLE5600.0
VENTILATEUR250.0

Slectionnez
unionbasedejointureavecutilisationdeCASE
SELECTCASE
WHENOBJ_NOMISNULL
THENMAC_NOM
ELSEOBJ_NOM
ENDASNOM,
CASE
WHENOBJ_PRIXISNULL
THENMAC_PRIX
ELSEOBJ_PRIX
ENDASPRIX
FROMT_OBJETO
FULLOUTERJOINT_MACHINEM
ONO.OBJ_NOM=M.MAC_NOM
ANDO.OBJ_PRIX=M.MAC_PRIX
ORDERBYNOM,PRIX

Slectionnez
NOMPRIX

ASSIETTE26.5
AVIONNULL
LIVRE128.0
MOTO43528.0
PERCEUSE259.98999
PERCEUSE260.0
RVEIL128.0
TABLE5600.0
VENTILATEUR250.0

Sansceslments,pointdesalutpourfairel'union...
6.Aquoiserventlesprocdurestockes?

http://sqlpro.developpez.com/cours/sqlaz/techniques/

14/24

16/2/2015

LespetitspapiersdeSQLproTechniquesdesSGBDR
Uneprocdurestocke,n'estniplusnimoinsqu'unboutdecodequis'excutedirectementsurleserveur.Ellepeutraliserlesmmes
traitementsquevousraliseriezparducodeclient.Disonsdonctoutdesuitequel'onpeutparfaitements'enpriver...
Maisalorsquelestl'intrtd'uneprocdurestocke?
D'abordlacentralisation...Quevotrecodeclientsoitunclientlourdouunclientlger,c'estlemmeappelquipourratrefait.
Ensuitelascurit...votrecodepeuttretransactionndansunenvironnementhyperscuriscequiestrarementlecasduposte
client.
Enfinlarapidit...quimieuxquevotreSGBDRestcapabledetraiterdesdonnessituesdansdestables?Mmesil'onutiliseuncode
clienthyperpointu(C++,Delphi...)lescotsinduitsparlesalleretretourdesdonnessurlerseauresteronstoujourspnalisant,sans
parlerqu'enmatiredetraitementdedonnestabulaire,votreSGBDRferatoujoursmieuxavecsonoptimiseurquevotrepauvrecode
futiloptimis.
Autrementdit,uneprocdurestockeestl'endroitidalpourpiloterlestransactions.
Unexempleconcret...
Soitunetabledesclientsetdesadressesdesclients(pourMSSQLServer).Onconservetouteslesadressesdesclientsafindegrerleur
obsolescense.Notezquel'onutiliseunautoincrment(IDENTITY)...

Slectionnez
CREATETABLET_CLIENT
(CLI_IDINTEGERIDENTITYNOTNULLPRIMARYKEY,
CLI_NOMVARCHAR(32))

Slectionnez
CREATETABLET_ADRESSE
(ADR_IDINTEGERIDENTITYNOTNULLPRIMARYKEY,
CLI_IDINTEGERFOREIGNKEYREFERENCEST_CLIENT(CLI_ID),
ADR_VOIEVARCHAR(64)NOTNULL,
ADR_CPCHAR(5)NOTNULL,
ADR_VILLEVARCHAR(32)NOTNULL)

Cequel'ondsire,c'esttreassurqu'eninsrantunnouveauclient,onyinsreaussil'adresse.Ornoussavonsqu'iln'estpaspossible
d'insrersimultanmentdansdeuxtablesdiffrentesavecunordreSQLbasique.Ceproblmepeutaismenttrecontournerparune
procdurestocketransactionne...

Slectionnez
CREATEPROCEDURESP_INS_CLIADR
@CLI_NOMVARCHAR(32),
@ADR_VOIEVARCHAR(64),
@ADR_CPCHAR(5),
@ADR_VILLEVARCHAR(32)
AS
variablepourrcuprerl'identifiantautoinsr
DECLARE@CLI_IDINTEGER
dbutdelatransaction
BEGINTRANSACTION
insertiondansT_CLIENT
INSERTINTOT_CLIENT(CLI_NOM)
VALUES(@CLI_NOM)
IF@@ERROR<>0
GOTOLBL_ERREUR
rcuprationdudernierautoincrmentinsr
SET@CLI_ID=@@IDENTITY
insertiondansT_ADRESSE
INSERTINTOT_ADRESSE(CLI_ID,ADR_VOIE,ADR_CP,ADR_VILLE)
VALUES(@CLI_ID,@ADR_VOIE,@ADR_CP,@ADR_VILLE)
IF@@ERROR<>0
GOTOLBL_ERREUR
validation
COMMIT
RETURN
annulationsil'undesdeuxrequtesd'insertionprovoquuneerreur
LBL_ERREUR:
ROLLBACK

Dslors,l'appeldecetteprocdureavecdebonsparamtres,vaajouterleslignesdanslesdeuxtablessimultanment:

Slectionnez
SP_INS_CLIADR'DUPONT','25chemindesvendanges','84190','BEAUMESDEVENISE'

Slectionnez

Slectionnez

SELECT*
FROMT_CLIENT

SELECT*
FROMT_ADRESSE

Slectionnez

Slectionnez

CLI_IDCLI_NOM

2DUPONT

ADR_IDCLI_IDADR_VOIEADR_C

2225chemindesvendanges84190

CQFD...
Enrevanche,uneprocdurestockenedoitjamaiss'occuperdefairedelalectureseule(unesimplerequtemmecomplexesuffiten
gnral)oudelaprsentationdedonnes(votrecodeclientseratoujoursplusaptequevotreSGBDRpourtouslesaspects"cosmtiques"!).
LanormeSQLn'aquasimentriendfinisurlesujet.Oupluttdevraisjedirequelafaiblessedelanormeenmatiredeprocdurestocke
esttellequ'apartlamanipulationdescurseur,chaquediteurdeSGBDRafabriquunlangageprocduralspcifiquesonserveur.
PourOracle,celangagec'estPL/SQL(ProgrammingLanguage/SQL),pourSybaseetMSSQLServer,c'estTransactSQL,pourInterBase,c'est

http://sqlpro.developpez.com/cours/sqlaz/techniques/

15/24

16/2/2015

LespetitspapiersdeSQLproTechniquesdesSGBDR
ISQL(InteractiveSQL)...etc.
UnexempledulangageTransactSQLetdesespossibilitsestvisibleici.Ils'agitduTransactSQLdeMicrosoftSQLServer7.
7.AquoiserventlesUDF?

UserDefineFunction/Fonctionsutilisateurs
LesUDF(USerDefineFunctionoufonctionutilisateur)sontunrcentajoutdeSQLpuisqu'ilsviennentdelaversion3(1999)delanorme.Ce
sontdesfonctionsquetoututilisateurpeutcoderdanssabasededonnesetquipeuventtreappelesdansdesrequtesSQL.
CeconceptexistaitdjdanscertainsSGBDRcommeInterBase.LesfonctionsdeInterBasedoiventtreralisesdansunlangageextrieuret
sont"branches"auserveurparexempleparlebiaisdeDLLsousenvironnementMSWindows.
DanslanormeSQL3,cesfonctionspeuventtreralisessoitenSQL,soitdansunlangageexternereconnu(Ada,C,Fortran,Cobol,MUMPS,
Pascal,PL1).Enpratiquecelapourratrefaitsurd'autreslangagesvoirelelangageprocduralduserveur.

7.1.Quelintrt?
L'intrtdesUDFrsidedanslapossibilitd'ajoutdefonctionspuissantesounonencoreralisesdanscellefourniesparl'diteurdevotre
SGBDR.Autrementdit,ajouterlesmanquesdudialecteSQLdevotreSGBDR.
Ilyaunautreintrtmoinsvident.Sivousdevezraliserdesapplicationsmultiserveurs,c'estdiredesapplicationssusceptibledetourner
surdiffrentsSGBDR,etsilesSGBDRcibleimplmentelesUDF,alorsilestpossiblededfinirdanschaqueserveurunebibliothqued'UDF
quipermettrad'uniformisertouteslesrequtesquipourronts'adresserindiffrementl'unoul'autredesSGBDRcible!

7.2.Unexemple?
Pourlapeinejevousencommuniquetrois!
LepremierexempledonnelaconstantePIutilisabledansn'importequellerequte:

Slectionnez
CREATEFUNCTIONPI()
LANGUAGESQL
RETURNSDECIMAL(16,15)
CONTAINSSQL
RETURN3.141592653589793

Slectionnez
SELECTDIAMETRE*PI()
FROMT_CERCLE

Lesecondexemplemontreunefonctiondeconversiondesfrancseneuros:

Slectionnez
CREATEfunctionfranc_euros(VALEURFLOAT)
LANGUAGESQL
RETURNSDECIMAL(16,2)
RETURNSNULLONNULL
DECLAREVALEUROSDECIMAL(16,2)
SETVALEUROS=CAST(VALEURasdecimal(16,2))/6.55957
RETURNCAST(VALEUROSasFLOAT)

Slectionnez
SELECTfranc_euros(MONTANT_TTC)
FROMT_FACTURE

LetroisimemontrecommentonpeututiliserunlangageexternepourraliseruneUDF.L'exemplederoutineexterneestenCetcompteles
motsd'unCLOB(CharacterLargeOBject):

Slectionnez
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include<sqludf.h>
#include<sqlca.h>
#include<sqlda.h>
#ifdef__cplusplus
extern"C"
#endif
voidSQL_API_FNwordcount(
SQLUDF_CLOB*in1,
SQLUDF_INTEGER*out,
SQLUDF_NULLIND*in1null,
SQLUDF_NULLIND*outnull,
SQLUDF_TRAIL_ARGS){
SQLUDF_INTEGERcount=0;
SQLUDF_INTEGERind;
SQLUDF_SMALLINTblank=0;
for(ind=0;ind<in1>length;ind++){
if(blank==0&&in1>data[ind]!=''){
blank=1;
count++;
}elseif(blank==1&&in1>data[ind]==''){
blank=0;
}/*endif*/
}/*endfor*/

Slectionnez
CREATEFUNCTIONWORD_COUNT(MyTextCLOB)
LANGUAGEC
PARAMETERSTYLESQL
DETERMINISTIC
NOSQL
EXTERNALNAME"UDFbibC/Wordcount"
RETURNSINTEGER
DECLAREN_WORDSINTEGER
SETN_WORDS=Wordcount(MyText)
RETURN(N_WORDS)

*out=count;
*outnull=0;
}

AcestadecertainespartiesdeladclarationdelafonctionsontspcifiquesauSGBDR,enparticulierladclarationEXTERNALNAMEetl'appel

http://sqlpro.developpez.com/cours/sqlaz/techniques/

16/24

16/2/2015

LespetitspapiersdeSQLproTechniquesdesSGBDR
delafonction.
CertainsSGBDRcommeInterBaseimplmententdepuislongtempsdesUDFnotammentsousformedemodulesexternesquel'onpeutcrire
danslelangagedesonchoix,commeCouDelphi,conditionquecesfonctionssoientplacesdansunebibliothquesousformedeDLLou
quivalent(dpenddel'OS).
Exempled'UDFexternepourInterBaseralisessousDelphi:

Slectionnez
//fichierprojetdelphi"UdfIBsqlPro.dpr"
libraryUDFibSQLpro;
uses
SysUtils,
Classes,
UudfIBin'UudfIB.pas';
{$R*.res}
//functionflip(s:pchar;pivot:integer):pchar;
//functionreverse(s:pchar):pchar;
begin
end.

Slectionnez
//fichierd'unitdelphi"UudfIB.pas"
unitUudfIB;
interface
Uses
IBexternals,IBheader,IBIntf;
//intervertitledbutetlafind'unechane
//parrapportaucaractrepivot
functionflip(s:pchar;pivot:integer):pchar;cdecl;
//inverseleslettresd'unmot
functionreverse(s:pchar):pchar;cdecl;
Exports
flip,reverse;
implementation
functionflip(s:pchar;pivot:integer):pchar;cdecl;
var
sd:string;
sout:string;
begin
iflength(s)=0
then
begin
flip:=s;
exit;
end;
sd:=string(s);
ifpivot>=length(sd)
then
begin
flip:=s;
exit;
end;
sout:=copy(sd,1,pivot)+copy(sd,pivot+1,length(sd)pivot);
flip:=PChar(sd);
end;
functionreverse(s:pchar):pchar;cdecl;
var
sd:string;
sout:string;
i:integer;
begin
sd:=string(s);
iflength(sd)=0
then
begin
sout:=s;
exit;
end;
sout:='';
fori:=1tolength(sd)
do
sout:=sout+sd[i];
reverse:=PChar(sout);
end;
Initialization
IsMultithread:=true;
CheckIBloaded;
end.

Slectionnez
/liaisonentrelesUDFetlesmodulesexternes
DECLAREEXTERNALFUNCTIONFLIP

http://sqlpro.developpez.com/cours/sqlaz/techniques/

Slectionnez

17/24

16/2/2015

LespetitspapiersdeSQLproTechniquesdesSGBDR
CSTRING(256),DOUBLEPRECISION
RETURNSCSTRING(256)
ENTRY_POINT"flip"
MODULE_NAME"C:\IB\UDF\UdfIBsqlPro.dll"
DECLAREEXTERNALFUNCTIONREVERSE
CSTRING(256)
RETURNSCSTRING(256)
ENTRY_POINT"reverse"
MODULE_NAME"C:\IB\UDF\UdfIBsqlPro.dll"

exempled'utilisation
SELECTFLIP(COL1,3),REVERSE(COL2)
FROMTEST

COMMIT

Exempled'UDFpourMSSQLServer2000:

Slectionnez
FredBROUARD20021011
extraitd'unechainedecaractresuniquementleschiffressansaucunespace
CREATEFUNCTIONFN_FORMATE_CHIFFRE_SEUL(@VALUEVARCHAR(8000))
RETURNSVARCHAR(8000)
AS
BEGIN
effetsdebord:NULL
IF@VALUEISNULL
RETURN@VALUE
effetdebord:chainevide
IF@VALUE=''
RETURN@VALUE
cascourant
DECLARE@NEWVALUEVARCHAR(8000)
SET@NEWVALUE=''
DECLARE@IINTEGER
SET@I=1
WHILE@I<=LEN(@VALUE)
BEGIN
IFSUBSTRING(@VALUE,@I,1)BETWEEN'0'AND'9'
SET@NEWVALUE=@NEWVALUE+SUBSTRING(@VALUE,@I,1)
SET@I=@I+1
END
RETURN@NEWVALUE
END

Slectionnez
FredBROUARD20021011
extraitd'unechainedecaractresuniquementdeslettremajusculesnondiacritqiues,
deschiffresetdesespacesnondoublonns(conversiondescaractresdiacritiques)
CREATEFUNCTIONFN_FORMATE_MAJ_SANS_DIAC(@VALUEVARCHAR(8000))
RETURNSVARCHAR(8000)
AS
BEGIN
effetsdebord:NULL
IF@VALUEISNULL
RETURN@VALUE
effetdebord:chainevide
IF@VALUE=''
RETURN@VALUE
cascourant
DECLARE@NEWVALUEVARCHAR(8000)
SET@NEWVALUE=''
DECLARE@IINTEGER
SET@I=1
DECLARE@CCHAR(1)
DECLARE@LETTREBIT
SET@VALUE=UPPER(@VALUE)
WHILE@I<=LEN(@VALUE)
BEGIN
SET@LETTRE=0
SET@C=SUBSTRING(@VALUE,@I,1)
IFCAST(@CASVARBINARY(32))BETWEENCAST('0'ASVARBINARY(32))
ANDCAST('9'ASVARBINARY(32))
ORCAST(@CASVARBINARY(32))BETWEENCAST('A'ASVARBINARY(32))
ANDCAST('Z'ASVARBINARY(32))
BEGIN
SET@NEWVALUE=@NEWVALUE+SUBSTRING(@VALUE,@I,1)
SET@LETTRE=1
END
ELSE
BEGIN
IF@C=''OR@C=''OR@C=''OR@C=''OR@C=''OR@C=''OR@C=''
OR@C=''OR@C=''OR@C=''OR@C=''OR@C=''
BEGIN
SET@NEWVALUE=@NEWVALUE+'A'
SET@LETTRE=1
END
IF@C=''OR@C=''
BEGIN
SET@NEWVALUE=@NEWVALUE+'AE'
SET@LETTRE=1
END
IF@C=''OR@C=''
BEGIN
SET@NEWVALUE=@NEWVALUE+'C'
SET@LETTRE=1
END
IF@C=''OR@C=''OR@C=''OR@C=''OR@C=''OR@C=''OR@C=''OR@C=''
BEGIN
SET@NEWVALUE=@NEWVALUE+'E'
SET@LETTRE=1
END
IF@C=''OR@C=''OR@C=''OR@C=''OR@C=''OR@C=''OR@C=''OR@C=''
BEGIN
SET@NEWVALUE=@NEWVALUE+'I'

http://sqlpro.developpez.com/cours/sqlaz/techniques/

18/24

16/2/2015

LespetitspapiersdeSQLproTechniquesdesSGBDR
SET@LETTRE=1
END
IF@C=''OR@C=''
BEGIN
SET@NEWVALUE=@NEWVALUE+'N'
SET@LETTRE=1
END
IF@C=''OR@C=''OR@C=''OR@C=''OR@C=''OR@C=''
OR@C=''OR@C=''OR@C=''OR@C=''
BEGIN
SET@NEWVALUE=@NEWVALUE+'O'
SET@LETTRE=1
END
IF@C=''OR@C=''
BEGIN
SET@NEWVALUE=@NEWVALUE+'OE'
SET@LETTRE=1
END
IF@C=''
BEGIN
SET@NEWVALUE=@NEWVALUE+'SS'
SET@LETTRE=1
END
IF@C=''OR@C=''OR@C=''OR@C=''OR@C=''OR@C=''OR@C=''OR@C=''
BEGIN
SET@NEWVALUE=@NEWVALUE+'U'
SET@LETTRE=1
END
IF@C=''OR@C=''OR@C=''
BEGIN
SET@NEWVALUE=@NEWVALUE+'Y'
SET@LETTRE=1
END
IF@LETTRE=0
SET@NEWVALUE=@NEWVALUE+''
END
SET@I=@I+1
END
ddoublonnagedesespacesparasites
SET@VALUE=@NEWVALUE
SET@NEWVALUE=''
SET@I=1
SET@LETTRE=0
WHILE@I<=LEN(@VALUE)
BEGIN
SET@C=SUBSTRING(@VALUE,@I,1)
IFCAST(@CASVARBINARY(32))=CAST(''ASVARBINARY(32))
BEGIN
IF@LETTRE=1
SET@NEWVALUE=@NEWVALUE+@C
SET@LETTRE=0
END
ELSE
BEGIN
SET@NEWVALUE=@NEWVALUE+@C
SET@LETTRE=1
END
SET@I=@I+1
END
RETURNLTRIM(@NEWVALUE)
END

Slectionnez
/*obtentiondelalistedescolonnesd'untable*/
F.BROUARD20021010
CREATEFUNCTIONFN_LIST_COLUMNS(@TABLE_NAMEVARCHAR(128))
RETURNSVARCHAR(8000)
AS
BEGIN
DECLARE@LIST_COLSVARCHAR(8000)
SET@LIST_COLS='('
SELECT@LIST_COLS=@LIST_COLS+COLUMN_NAME+','
FROMINFORMATION_SCHEMA.COLUMNS
WHERETABLE_NAME=@TABLE_NAME
SET@LIST_COLS=SUBSTRING(@LIST_COLS,1,LEN(@LIST_COLS)1)+')'
RETURN(@LIST_COLS)
END

7.3.Peutons'enpasser?Faireautrement??
Bienentendu...OnpeutraliserquelquesunesdesUDFdansdesvuesparexempleoudesprocduresstockes.Onpeutencorefaireun
traitementdesdonnesreuessurleposteclient.Maisdanscederniercas,lesperformancesnesontpastrsintressantes.
AutrementditlesUDFnesontpasabsolumentncessaires,maisbienutiles!
8.Lajournalisation
oucommentsontraliseslestransactionsparleserveur
Lajournalisationestlemcanismedebasepermettantletransactionneletassurantl'intgritdesdonnesdelabase.

8.1.Aquoiasert?
CelasertenregistrertouteslesmanipulationsdedonnesquisontlancespardesrequtesSQLsurleserveur,afindelesexcuterdela
manirelaplusintgrepossibleafinquetoutproblmesurvenantlorsd'unetransactionn'induisepasune"dsintgration"delabase...
Lejournalcaptetouteslesdemandesetassureunmcanismederepriseautomatiquedanslecasd'unepanne,maisaussigrelesROLLBACK
etCOMMIT.
Aucunebasededonnesrelationnellegrantdestransactionsnepeutsepasserdecetypedemcanisme.
Attention:uneerreurfrquenteestdecroirequ'l'aidedujournalonpeutsuivrecequeteloutelutilisateurapufairesurlabase,oubien

http://sqlpro.developpez.com/cours/sqlaz/techniques/

19/24

16/2/2015

LespetitspapiersdeSQLproTechniquesdesSGBDR
quellesonttlesmodificationssurvenuedanstelleoutelletable.Lajournalisationestenprincipeunmcanismesstrictementinterneau
SGBDRetdoncrservsonseulusage.Iln'estdoncpaslisiblepourunutilisateur,ftiladministrateurdelabasededonnesoudu
serveur.

8.2.Commentamarche?
Jen'entreraispasdanslesdtailsdel'implmentationdelajournalisationdeteloutelditeur.Jevaissimplementvousexpliquercomment
celamarchedemaniregnrique...
Lorsqu'unerequteduDML(DataManipulationLanguage)c'estdireunordreSELECT,INSERT,UPDATEouDELETE,estenvoyeauserveur,
lejournalcritdanssonfichierleslmentsrelatifquelutilisateurserapportecettedemandeainsiquequelquesparamtrescommeladate
etl'heuredelademande.Lejournalinscritlarequtetellequ'illatrouveainsiqu'unmarqueurpoursignalerledbutdelatransaction
(n'oubliezpasquetouterequte,laplussimplesoitelleestunetransactionpartentire).
Cesinformationspourraientseprsentercommesuit:

Slectionnez
REQUESTFOR:
USER=SQLpro
CONNECTION=0x001252
SERVER=SRV_PROD
DATABASE=DB_CLIENT
QUERYIS:
UPDATET_PRIX
SETPRX_PRIX=PRX_PRIX*1.1
ENDQUERY
START=2002091113:24:55.235
BEGINTRANSACTION056512300651324568456521

LeSGBDRsignaleauclientquelarequteatpriseencompteetluidemanded'attendreleretourd'excution.
NoussupposonsquelatableT_PRIXcontiennelesdonnessuivantes:

Slectionnez

Slectionnez

CREATETABLET_PRIX
(PRX_IDINTEGERNOTNULLPRIMARYKEY,
PRX_PRIXFLOATNOTNULL)

INSERTINTOT_PRIXVALUES(1,254.15)
INSERTINTOT_PRIXVALUES(2,98541.24)
INSERTINTOT_PRIXVALUES(3,8741.99)

NousallonsmaintenantinterromprelecourantlectriquedenotreserveurtoutinstantpourvoircommentsecomporteleSGBDR...
L'interruption
intervient

justeaprs
Slectionnez
l'crituredu
marqueur
signalantle BEGINTRANSACTION056512300651324568456521
dbutdela
transaction
Lejournalestrelu"l'envers"etleSGBDRessayederetrouverladerniremarquedetransactionvalideourollback,puisreprendla
lecturedujournaletredmarreletravailsurlestransactionsinacheves.Ilinterdittoututilisateurdeluienvoyerdesrequtestantqu'iln'a
pasretrouvsonpointd'quilibre(intgritdesdonnes)...
Leserveur
inscritdans
lejournal
lesdonnes
concernes
parla
modification.
Avantlafin
dece
processus,
lecourant
estcoup...

Slectionnez
PREVIOUSINFORMATIONS:
OBJECT=TABLE(T_PRIX)
DATA=:KEY(PRX_ID),COLS(PRX_PRIX)
ARE:
1,254.15
2,98541.24

Lejournalestrelu"l'envers"etleSGBDRessayederetrouverladerniremarquedetransactionvalideourollback,puisreprendla
lecturedujournaletredmarreletravailsurlestransactionsinacheves.Silesdonnesconcernesparlamodificationsn'ontpasttoutes
crites,ilsupprimecellesdjprsentesetrecommencesontravail...
Leserveur
recommence
inscrire
dansle
journalles
donnes
concernes
parla
modification.
Puisil
calculeles
misejour
etlesinscrit
dansle
journal...
Avantlafin
dece
processus,
lecourant
estcoup...

Slectionnez
PREVIOUSINFORMATIONS:
OBJECT=TABLE(T_PRIX)
DATA=:KEY(PRX_ID),COLS(PRX_PRIX)
ARE:
1,254.15
1,98541.24
1,8741.99
ENDPREVIOUSINFORMATIONS
FUTUREINFORMATION:
OBJECT=TABLE(T_PRIX)
DATA=:KEY(PRX_ID),COLS(PRX_PRIX)
ARE:
1,279.4
2,108395,10

Lejournalestrelu"l'envers"etleSGBDRessayederetrouverladerniremarquedetransactionvalideourollback,puisreprendla
lecturedujournaletredmarreletravailsurlestransactionsinacheves.Silesdonnesconcernesparlamodificationsn'ontpasttoutes

http://sqlpro.developpez.com/cours/sqlaz/techniques/

20/24

16/2/2015

LespetitspapiersdeSQLproTechniquesdesSGBDR
calculesetinscrite,ilsupprimecellesdjprsentesetrecommencesontravail...
Leserveur
recommence
inscrire
dansle
journalles
donnes
calcules
pour
l'UPDATE.Il
commence
recopierces
informations
dansla
table.Avant
lafindece
processus,
lecourant
estcoup...

Slectionnez
PREVIOUSINFORMATIONS:
OBJECT=TABLE(T_PRIX)
DATA=:KEY(PRX_ID),COLS(PRX_PRIX)
ARE:
1,254.15
1,98541.24
1,8741.99
ENDPREVIOUSINFORMATIONS
FUTUREINFORMATION:
OBJECT=TABLE(T_PRIX)
DATA=:KEY(PRX_ID),COLS(PRX_PRIX)
ARE:
1,279.4
2,108395,10
3,9615,10
ENDFUTUREINFORMATION

Lejournalestrelu"l'envers"etleSGBDRessayederetrouverladerniremarquedetransactionvalideourollback,puisreprendla
lecturedujournaletredmarreletravailsurlestransactionsinacheves.Silesdonnesconcernesparlamodificationsn'ontpasttoutes
rpercutesdanslatable,ilrecommencelapremirevaleur...

Slectionnez
Leserveur
afinide
rpercuter
lesdonnes
calcules
pour
l'UPDATE
dansla
tableet
inscritune
marquede
finde
transaction.

PREVIOUSINFORMATIONS:
OBJECT=TABLE(T_PRIX)
DATA=:KEY(PRX_ID),COLS(PRX_PRIX)
ARE:
1,254.15
1,98541.24
1,8741.99
ENDPREVIOUSINFORMATIONS
FUTUREINFORMATION:
OBJECT=TABLE(T_PRIX)
DATA=:KEY(PRX_ID),COLS(PRX_PRIX)
ARE:
1,279.4
2,108395,10
3,9615,10
ENDFUTUREINFORMATION
TRANSACTIONCOMPLETE
WORKCOMMITED

Etvoil!Riendeplussimpleenapparence...Rajoutezylagestiondesverrousetuneconcurrencedetraitement...etdonnezm'endes
nouvelles!!!

8.3.Peutons'enpasser?Faireautrement??
Onpeut,bienentendus'amuserrinventerlaroue...Implmenterunejournalisationsurunebasequienestdpourvuen'arien
d'impossible.Enrevanchelacomplexitd'untelprogrammeenmultiutilisateuresttellequ'ilyafortparierquevousmettrezquelques
annesenraliserunperformant...D'ailleurssachezquelagestiondestransactionsestencoursdedveloppementpourleSGBDMySQL,
depuis...combiendetempsdj?Oui,oui,jesais,ceseradanslafutureversion...
Maisquejevousrassure,laplupartdesvritablesSGBDRfontceladepuis...combiendetempsdj?Ahoui,deuxdcennies!
9.MySQLestilvraimentrapide?
Vousvousdoutezbienquesij'aicritcetitreracoleur,c'estparcequejepossdequelquesargumentspourvousconvaincrequesapseudo
rapiditestunleurre!
Oui,MySQLestrapide.Enlectureseulementetencorejevaisymettreunbmol...Commeilnegrepaslestransactions,ilconviendraitde
comparercequiestcomparable.Dansletest"crashme"MySQLatcomparOracle,SQLServer,DB2,InterBase...etc,c'estdiretout
untasdeSGBDRquitravaillentavecdestransactionsetfontdoncdelajournalisationcontrairementMySQLquinefaitriendetoutcela!
Autrementdit,cetestpnalised'embletouslesSGBDRquionttinscritencomparaison.NotonsquelesseulsSGBDRquinepratiquentpas
letransactionnelcommeParadox,FoxProoudBaseonttsoigneusementcarts...Curieuxnon?Onyaprissoinquandmmed'ylaisser
Access,leplusmauvaisetlemoinsperformantdesSGBDRfonctionnantenmodefichiers.
Lejeudetest,atcritpourMySQL,parlesauteursdeMySQL.QuediraitonsiOracleouMicrosoftfaisaitsonproprejeudedonneset
tablissaitsespropresrequtesafindesecomparerd'autresSGBDR?Qu'ils'arrangeraitpourarrivervainqueurnon?
Orlesrarestestsquiontteffectuspardespersonnesoudesorganismesindpendantsetentoutsrnit,montrentqueMySQLn'estpas
rapide,loins'enfaut,surtoutencontextedeconcurrence.IlarrivemmeMySQLde"tomber"assezrapidementdsquequelques
utilisateurssepressentpourlancerleursrequtes.
Voicileslmentsd'untestcomparatifeffectuentrePostGreSQLetMySQL.IlmontreclairementqueMySQLestendessousdes
performancesannoncesetpratiquementincapabled'unemonteenchargecorrecte.
Voustrouverezletestetsesconditionsdansl'articledeTimPerdue,publisurPHPbuilder:
http://www.phpbuilder.com/columns/tim20001112.php3
Anoterquelatraductionquiatfaiteparl'quipedephpteamenfranaisdonnedefaussesindicationsenprtendantqueMySQLestplus
rapidequePostGreSQLcequi,detoutevidenceestfaux,tantlalecturedesgraphiquesqu'lalecturedutexte.Peuttredoitonyvoir
l'originedelarumeursurlapseudorapiditdeMySQL?
Jenedonneraisqu'unseulextraitdecettetude,leplusdramatiquepourMySQL.Voiciungraphiquequirsumelasituation:

http://sqlpro.developpez.com/cours/sqlaz/techniques/

21/24

16/2/2015

LespetitspapiersdeSQLproTechniquesdesSGBDR

CetestestpratiqusurunepageHTMLquirequiert16requtessurunedouzainedetables.Demultiplesclientsattaquentcettepage.Pour
picerunpeuleproblme,25%destransactions(uniquementsurPostGreSQLpuisqueMySQLnepratiquepaslachose)sontannulespar
ROLLBACK.
A5clientssimultansMySQLestincapablededonneruneseulepageentireenmoinsd'uneseconde,tandisquePostGreSQLensertpresque
2...Maisloulebtblesse,c'estqu'aplusde20utilisateurssimultanMySQLn'existeplus!Enrevanche,PostGreSQLadaptelesressources
dusystmeetsertlespagesdemandesdeplusenplusvite...incroyablenon?
Aujourd'huiauxUSA,unmouvementcommences'emparerdunetetconcernelefreeSGBDR.LesdusdeMySQLsecomptentennombre
etpassentpourunegrandemajoritdevraiSGBDRcommePostGreSQL,FireBirdoud'autressystmesmoinsconnuscommeOcelotou
SAPdb.Cemouvementadjatteintlemarchallemand.
Untelmouvementcommences'amorceraussienFrance.Lessocitsquigravitentautourdecemarchprsentedesressources
notammentsurPostGreSQLenfranais,alorsquecederniertaitencoreconfidentieldanslalanguedeMolire.C'estainsiquel'diteur
CampusPress,atraduitunouvragetrsintressantsurPostGreSQL,dlaplumesd'auteursAutrichiens!
LeseulinconvnientdePostGreSQLestqu'iln'offrepasdeprocduresstockes.Maisilestpourvudesmcanismesd'intgritrfrentielle,
desfonctionsutilisateurs,dedclencheurs,cequienfaitundesmeilleurschoixdanslecadred'unearchtecturentiersdanslaquelleles
procesusmtierssontdportsversunserveurd'objetoud'application.
NuldoutequeMySQLavcuetquePostGreSQLassuredsormaislarelve!
CependantMySQLresteunbonchoixparsasimplicitpourdessitesdocumentairesdanslesquelsunseulutilisateurvaallermodifierles
donnesetdontlenombred'utilisateurssimultannedpassepasladizaine.
***
Al'heureouj'crisceslignesunnouvelarticlevientsemerletroubleenprsentantMySQLetsestransactions(versionbta)aussirapide
qu'Oracle9ietbienplusvlocequeMSSQLServeretSybaseASEhttp://www.eweek.com/article2/0,3959,293,00.aspletoutsurplateforme
Windows2000server.Nanmoinsonnesaitpasquelniveaud'isolationatprisencomptepourchaqueSGBDR.Pardfautceluid'Oracleest
maximumetceluideMSSQLServerest"READCOMMITED".NotonsenoutrequelaconnexionJDBCn'estquandmmepaslestandard
qu'adoptelamajoritdesdveloppeursSGBDRaujourd'hui!
Enconclusion,unarticleetunbenchmarkrelativementpartiel,maisuneaffairesuivre!
10.Quelquesremarquesde...
DrQ:
PourcequiestdesrsultatsdeMySQL,anecorrespondpasexactementcequej'avaisvucommetests.MySQLtaitplusrapideque
PostgreSQLavecunpetitnombred'utilisateurs(<10).Biensurpourdesrequtessimples.
SQLpro:
Lestestcomparatifsdisponiblesjusqi'icitaitunpeuancien.LaversionactuelledePostGreSQLatnettementamliorequestion
performances.Cependant,c'estsousLinuxquePostGreSQLvaleplusvitecariln'apasbesoindel'mulationCygWin.
OlivierNepomiachty:
jeneconnaispasPostGreSQL.
lamigrationestellefacile?
FautilrcrirelecodeSQL?
Lamigrationdestablessefaitellesanssoucis?
SQLpro:
PostGreSQLestassezfacileabordersil'onconnaitSQLetlesbasesdedonnes.L'excellentbouquindeCampusPress,peutservirdebase
unbonapprentissage.DepluslelangageprocduraldePostGreSQL(PG/SQL)esttrspricheduPascaldoncdeDelphi
PostGreSQLestasseznormatifcommeMySQL,monavisunemajoritderequtesnedevraientpasavoirbesoind'trercrites.Lereste
devraitsubirdetrslgresmodifications.
Aquelquesexceptionsprscommeletypearrayquin'existepassousPostGreSQL,ildoittrepossibledepasserdel'unl'autre.Lemieux
tantdedisposerd'unUserCasecommePowerDesignorouautreafind'effectuerunreverseengineeringpourreconstruireunebase
PostGreSQLpartird'unebaseMySQL.
Hachesse:
Ilt'asfaitquoiMySQLpourquetuluienveuilleacepoint?Ilt'asmourdu?
SQLpro:
Non,etpuisdetoutefaonjesuisvaccin)!!!SimplementjeregrettequedesproduitstoutaussisoupleetpluscontraintsqueMySQLaient
quasimentdisparus.JeneciteraisqueParadoxdontleformat,malgrqu'ilsoitunSGBDR"fichier"comprenanitl'intgritrfrentielleetun
ersatzdetransactionnel(rollbacklimit255lignes,tablescontenantlesvaleursavantmodificationousuppression).
Maispourmoi,unSGBDRdoitaumoinspossderl'intgritrfrentielledebase,etsil'onveutmonterencharge,letransactionnel.
RDM:
quelquesRemarques:
Sousrequtes:tun'expliquespaspourquoiunesousrequtepeutetrepluslentequ'unejointure,c'estdirequepourchque
enregistrementdelarequtemaitreonexcutelarequetedtail.c'estunpointtrsimportantqu'ilfautrappeler.C'estpurcaquel'on
viteleplussouventcegenrederequtebienquedanscertainscascommetulesoulignes,iln'yapasd'autrechoix.
TuesclairementattachamettreunmaximumdechoseauniveauduSGBD,alorsquej'aitendanceavoiruneapprocheinverse.les2
approchessontdfendablesselonlesarchitecturesapplicativesquel'onemploie.Jenevaisdoncpaslancerledbatladessus.
Concernanttaconclusionjesuisd'accord.cafaitdeja3ansquej'avaisremarquladiffrnceMySQL/PostgreSQLetc'estcemoment

http://sqlpro.developpez.com/cours/sqlaz/techniques/

22/24

16/2/2015

LespetitspapiersdeSQLproTechniquesdesSGBDR
queMySQLtaitdjtombauoubliettepourmoi.Leseulfaitqu'ilnegrepaslaconcurrenceetlestransactionsetdetoutesfacon
pnalisant.pourlereste(intgrit,storedproc,triggers,...)capeutetremoinsgnant(avecunearchitectureClient/serveur3eme
genration)maisbonontombedanslepointprcdent
SQLpro:
Iln'estpasvidentdedirequ'unesousrequtevatrepluslentequ'unejointure.Silajointureest"naturelle",alorsc'estprobable,danstous
lesautrescas,lephnomnebiendeschancesd'treinsensibledufaitdel'optimiseur.Maisilestvraiqu'unejointureestplusproprequ'une
requte.Latransformationn'estpastoujourspossiblehlas!
Amonsens,ilnefautpas"mettreunmaximumdechose"ctserveur...Maislestrictncessairemonavisrsidedanslerespectde
l'intgritdesdonnes.Untriggerpermettantdefaireduformatagededonnesneprsentepasd'intrt.Enrevanches'iltendl'intgrit
relationnelleilestindispensable.Ilenestdemmedestransactionsetdesprocduresstockes.Latendancetoutmettreductserveur
n'estpaslabonne.D'unautrect,leclientlgern'apasderllespossibilitspourtraiterlesdonnesalorsentrel'ajoutd'unserveurd'objet
(doncunemachinedeplus)oularalisationsystmatiquedestraitementsenprocduresstockesc'estunequestiondestratgieetdecot
quidoittrevaluepourchaquedveloppement.
Attentioncependantauxeffetsdemode...LesSGBDRexistenttelsquelsdepuismaintenant20ans...etsontassezperformants.
L'archictecture3tiersdepuisquelquesannes.EllecommenceadevenirmatureaveclescomposantsCORBA,latechnologieMIDASetles
nouveauxobjetCOMdrivsdel'architecture.netdeMS.EncequiconcerneleC/Sde3emegnration,jedirais...prudence(qui,comme
chacunlesait,estmredesret)mmesicertainestechnologiescommeXMLetenparticulierSOAPetleswebservices,prsententpriori
desinnovationsintelligentes.Maistoutlemondenedveloppepaspourleweb!
HenryCesbronLavau:
Aproposduparagraphe1.7:[...]L'idedemanipulerdestransactionsdepuisuncodeclient(VB,Delphi,Java,C++...)
Pourquoi,depuisquandc'estlelangagequitransacte?c'estuneaffairedecomposants,pasdelangage.
SQLpro:
Tuasentirementraison,maisj'aivoulufairesimpleenconfondantl'envoidel'ordredepilotagedelatransactionetlatransactionelle
mme.Sic'estbienleSGBDRquitransactionne,encorefautilluionnerlesordresBEGIN,COMMIT/ROLLBACK[TRANSACTION]depuisun
codequelconque,quipeuttrelecodeclient.Orleclientpeutparfaitementdciderd'allerboiresoncafentreleBEGINetleCOMMIT,oupire
interrompresonPC!
Livres
SQLdveloppement
SQLlecoursderfrencesurlelangageSQL
Avantd'aborderleSQL
Dfinitions
SGBDRfichierouclient/serveur?
Labasededonnesexemple(gestiond'unhtel)
ModlisationMERISE
MotsrservsduSQL
LeSQLdeAZ
Lesfondements
Lesimple(?)SELECT
Lesjointures,oucommentinterrogerplusieurstables
Groupages,ensemblesetsousensembles
Lessousrequtes
Insrer,modifier,supprimer
Crationdesbases
Grerlesprivilges("droits")
TouteslesfonctionsdeSQL
LestechniquesdesSGBDR
LeserreurlesplusfrquentesenSQL
LespetitspapiersdeSQLPro
ConfrenceBorland2003
L'hritagedesdonnes
Donnesetnormes
Modlisationparmtadonnes
OptimisezvotreSGBDRetvosrequtesSQL
Letemps,samesure,sescalculs
QBE,lelangagedeZLOOF
Desimagesdansmabase
Lajointuremanquante
Clefsautoincrmentes
L'indexationtextuelle
L'artdes"Soundex"
Uneseulecolonne,plusieursdonnes
Ladivisionrelationnelle,mytheouralit?
Gestiond'arborescenceenSQL
L'avenirdeSQL
Mthodesetstandards
Lesdoublons
SQLServer
Eviterlescurseurs
UnaperudeTRANSACTSQLV2000
SQLServer2000etlescollations
ScurisationdesaccsauxbasesdedonnesSQLServer
DesUDFpourSQLServer
SQLServeretlefichierdelog...
Paradox
Devieuxarticlespublisentre1995et1999dansladfunterevuePointDBF
(1)

http://sqlpro.developpez.com/cours/sqlaz/techniques/

23/24

16/2/2015

LespetitspapiersdeSQLproTechniquesdesSGBDR
Histoirehlasvridiquedueunbugduserviceinformatiquederservation!!!

Copyright2004FrdricBrouard.Aucunereproduction,mmepartielle,nepeuttrefaitedecesiteetdel'ensembledesoncontenu:textes,documents,images,etc.sansl'autorisationexpresse
del'auteur.Sinonvousencourezselonlaloijusqu'troisansdeprisonetjusqu'300000dedommagesetintrts.

ResponsablebnvoledelarubriqueSGBD&SQL:FrancisWalterContacterparemail

Developpez.com
Nouscontacter
Participez
Informationslgales

Services
ForumSGBD&SQL
Blogs
Hbergement

Partenaires

PlanetHoster

Copyright20002015www.developpez.com

http://sqlpro.developpez.com/cours/sqlaz/techniques/

24/24