<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://blog.netapsys.fr/index.php/feed/rss2/xslt" ?><rss version="2.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
  <title>Netapsys Blog - nvl</title>
  <link>http://blog.netapsys.fr/index.php/</link>
  <description></description>
  <language>fr</language>
  <pubDate>Tue, 07 Sep 2010 08:07:18 +0200</pubDate>
  <copyright>Netapsys 2008 - 2009</copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>Intégrité référentielle et utilisation de fonctions SQL, ou comment rendre au SGBD une partie de ses responsabilités.</title>
    <link>http://blog.netapsys.fr/index.php/post/2009/03/12/Integrite-referentielle-et-utilisation-de-fonctions-SQL-ou-comment-rendre-au-SGBD-une-partie-de-ses-responsabilites</link>
    <guid isPermaLink="false">urn:md5:87d2b7598160a6d97c7d2f2dc8cc49a6</guid>
    <pubDate>Thu, 12 Mar 2009 18:03:00 +0100</pubDate>
    <dc:creator>Darko Stankovski</dc:creator>
        <category>SQL</category>
        <category>clé primaire</category><category>clé étrangère</category><category>contrainte intégrité</category><category>ifnull</category><category>intégrité référentielle</category><category>nvl</category><category>sql</category><category>tutoriel</category>    
    <description>&lt;p&gt;Faisons suite au dernier billet de Céline en restant dans le domaine des bases de données et des petites astuces connues de tous mais jamais utilisées. Intéressons nous à la gestion de l'intégrité référentielle et au calcul d'identifiants en laissant la base faire ce qu'elle sait faire et éviter un développement applicatif inutile.&lt;/p&gt;    &lt;h3&gt;Contexte&lt;/h3&gt;


&lt;p&gt;Posons l'exemple. Soit donc une base avec les tables suivantes&amp;nbsp;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Categorie (id, libelle)&lt;/li&gt;
&lt;li&gt;SousCategorie (idCategorie, id, libelle)&lt;/li&gt;
&lt;li&gt;Employe (id, idSousCategorie, nom).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ah ces chers employés... Nous allons donc catégoriser les employés en catégorie et sous-catégorie ou pas. Une sous catégorie est donc automatiquement associée à une catégorie et un employé peut ou non être associé à une sous-catégorie. La clef primaire de chaque table est évidente. Mais on va compliquer un peu et définir que pour les sous-catégories, l'Id est relatif à la catégorie et n'est donc pas unique. Par contre, le couple est unique. Les champs &lt;strong&gt;Id&lt;/strong&gt; seront donc les clefs primaires pour les tables &lt;em&gt;Categorie&lt;/em&gt; et &lt;em&gt;Employe&lt;/em&gt; et la table &lt;em&gt;SousCategorie&lt;/em&gt; aura une clef composite &lt;strong&gt;idCategorie, id&lt;/strong&gt;.&lt;/p&gt;


&lt;p&gt;Évidemment, il faut ensuite poser les clefs étrangères. Sur ce modèle &quot;simple&quot;, elles sont claires&amp;nbsp;: &lt;em&gt;idSousCategorie&lt;/em&gt; d&lt;em&gt;'Employe&lt;/em&gt; référence &lt;em&gt;id&lt;/em&gt; de &lt;em&gt;SousCategorie&lt;/em&gt; et &lt;em&gt;idCategorie&lt;/em&gt; de &lt;em&gt;SousCategorie&lt;/em&gt; référence &lt;em&gt;id&lt;/em&gt; de &lt;em&gt;Categorie&lt;/em&gt;. Allons-y pour la création classique des tables sous MySql.&lt;/p&gt;

&lt;pre class=&quot;sql&quot;&gt;&lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;CREATE&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;TABLE&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;`categorie`&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`id`&lt;/span&gt; INT &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;AUTO_INCREMENT&lt;/span&gt;,
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`libelle`&lt;/span&gt;VARCHAR&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #cc66cc;&quot;&gt;30&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
    &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;PRIMARY&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;KEY&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;id&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; ENGIN&lt;span style=&quot;color: #66cc66;&quot;&gt;=&lt;/span&gt;InnoDB;
&amp;nbsp;
&lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;CREATE&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;TABLE&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;`souscategorie`&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`idcategorie`&lt;/span&gt; INT &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`id`&lt;/span&gt; INT &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`libelle`&lt;/span&gt;VARCHAR&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #cc66cc;&quot;&gt;30&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
    &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;PRIMARY&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;KEY&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;idcategorie, id&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;,
    CONSTRAINT &lt;span style=&quot;color: #ff0000;&quot;&gt;`FK_SOUSCATEGORIE`&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;FOREIGN&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;KEY&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;idcategorie&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
        &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;REFERENCES&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;`categorie`&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;`id`&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; ENGIN&lt;span style=&quot;color: #66cc66;&quot;&gt;=&lt;/span&gt;InnoDB;
&amp;nbsp;
&lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;CREATE&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;TABLE&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;`employe`&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`id`&lt;/span&gt; INT &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;AUTO_INCREMENT&lt;/span&gt;,
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`idsouscategorie`&lt;/span&gt;INT &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;DEFAULT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`nom`&lt;/span&gt;VARCHAR&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #cc66cc;&quot;&gt;40&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
    &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;PRIMARY&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;KEY&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;id&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;,
    CONSTRAINT &lt;span style=&quot;color: #ff0000;&quot;&gt;`FK_EMPLOYE`&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;FOREIGN&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;KEY&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;idsouscategorie&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
        &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;REFERENCES&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;`souscategorie`&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;`id`&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; ENGIN&lt;span style=&quot;color: #66cc66;&quot;&gt;=&lt;/span&gt;InnoDB;&lt;/pre&gt;


&lt;p&gt;Voilà. Incroyable et révolutionnaire. Bon, maintenant, regardons un peu la logique de traitement. On peut ajouter des catégories. On peut ajouter des sous-catégories à une catégorie existante. On peut créer un employé, et on peut affecter un employé à une sous-catégorie. Dans le même ordre d'idée, on peut supprimer un employé, une sous-catégorie si aucun employé ne lui est affecté, et une catégorie si elle ne possède pas de sous catégorie.&lt;/p&gt;


&lt;p&gt;Lors de la gestion des projets mettant en jeu une base qui ressemblerait à ça et l'applicatif qui va avec, on voit souvent la conception de la base s'arrêter là et les traitements remonter au niveau de l'applicatif. Ainsi, la fonctionnalité de suppression d'une catégorie supprimera toutes les sous-catégories avant de supprimer la catégorie. Fonctionnellement c'est correct, mais que d'énergie dépensée pour pas grand chose. Surtout si les règles sont que pour toute suppression de catégorie, les sous-catégories doivent être simplement supprimées et pour toute suppression de sous-catégorie, les employés doivent simplement en être désaffectés.&lt;/p&gt;


&lt;h3&gt;Gestion de l'intégrité référentielle&lt;/h3&gt;

&lt;p&gt;Les bases de données sont capables de gérer leur intégrité référentielle. Il suffit pour ça de rajouter une clause &lt;strong&gt;ON DELETE&lt;/strong&gt; aux contraintes de clef étrangère.&lt;/p&gt;


&lt;h4&gt;Cas de la suppression d'une sous-catégorie&lt;/h4&gt;

&lt;p&gt;Une sous-catégorie ne peut être supprimée que si aucun employé ne lui est affecté (contrainte &lt;em&gt;FK_EMPLOYE&lt;/em&gt;). Supprimer une sous-catégorie ne doit entraîner que la désaffectation de l'employé de ladite catégorie. Il suffit alors d'utiliser la clause &lt;strong&gt;ON DELETE SET NULL&lt;/strong&gt;. Ainsi lors de la suppression d'une sous-catégorie, tous les employés affectés à cette sous-catégorie verront leur champ &lt;em&gt;idsouscategorie&lt;/em&gt; modifié en &lt;em&gt;NULL&lt;/em&gt;. Le code pour créer cette table sera maintenant&amp;nbsp;:&lt;/p&gt;

&lt;pre class=&quot;sql&quot;&gt;&lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;CREATE&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;TABLE&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;`employe`&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`id`&lt;/span&gt; INT &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;AUTO_INCREMENT&lt;/span&gt;,
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`idsouscategorie`&lt;/span&gt;INT &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;DEFAULT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`nom`&lt;/span&gt;VARCHAR&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #cc66cc;&quot;&gt;40&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
    &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;PRIMARY&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;KEY&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;id&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;,
    CONSTRAINT &lt;span style=&quot;color: #ff0000;&quot;&gt;`FK_EMPLOYE`&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;FOREIGN&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;KEY&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;idsouscategorie&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
        &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;REFERENCES&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;`souscategorie`&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;`id`&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
        &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;ON&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;DELETE&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;SET&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; ENGIN&lt;span style=&quot;color: #66cc66;&quot;&gt;=&lt;/span&gt;InnoDB;&lt;/pre&gt;



&lt;h4&gt;Cas de la suppression d'une catégorie&lt;/h4&gt;

&lt;p&gt;Une catégorie ne peut être supprimée que si aucune sous-catégorie ne lui est affectée (contrainte &lt;em&gt;FK_SOUSCATEGORIE&lt;/em&gt;). Contrairement à l'employé, une sous-catégorie n'a aucun sens à elle toute seule. Ce coup-ci, il faudra utiliser la clause &lt;strong&gt;ON DELETE CASCADE&lt;/strong&gt;. Ainsi, pour la suppression d'une catégorie, la base supprimera toutes les sous-catégories s'y référant. Le code pour créer cette table sera maintenant&amp;nbsp;:&lt;/p&gt;

&lt;pre class=&quot;sql&quot;&gt;&lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;CREATE&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;TABLE&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;`souscategorie`&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`idcategorie`&lt;/span&gt; INT &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`id`&lt;/span&gt; INT &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`libelle`&lt;/span&gt;VARCHAR&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #cc66cc;&quot;&gt;30&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
    &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;PRIMARY&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;KEY&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;idcategorie, id&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;,
    CONSTRAINT &lt;span style=&quot;color: #ff0000;&quot;&gt;`FK_SOUSCATEGORIE`&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;FOREIGN&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;KEY&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;idcategorie&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
        &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;REFERENCES&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;`categorie`&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;`id`&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
        &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;ON&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;DELETE&lt;/span&gt; CASCADE&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; ENGIN&lt;span style=&quot;color: #66cc66;&quot;&gt;=&lt;/span&gt;InnoDB;&lt;/pre&gt;


&lt;p&gt;Ainsi, l'intégrité référentielle des données est toujours respectée quel que soit le contexte et est indépendante d'un applicatif. Supprimer une catégorie supprimera les sous-catégories affectées et la suppression d'une sous-catégorie désaffectera les employés affectés. En conséquence, le développement de l'applicatif n'est que facilité. Chaque entité a des responsabilités dédiées et limitées, avec comme conséquence la plus importante, le fait que quelle que soit l'action sur la base, l'intégrité référentielle est toujours respectée.&lt;/p&gt;


&lt;h3&gt;Ajout de sous-catégories&lt;/h3&gt;

&lt;p&gt;Revenons à nos sous-catégories. En ce qui les concerne, la clef primaire est une clef composite. Il est impossible d'utiliser des instructions comme &lt;em&gt;AUTO_INCREMENT&lt;/em&gt; car l'id de la sous-catégorie doit être relatif à la catégorie (catégorie 1, sous catégorie 1&amp;nbsp;; catégorie 1, sous catégorie 2&amp;nbsp;; catégorie 1, sous catégorie 3&amp;nbsp;; catégorie 2, sous catégorie 1&amp;nbsp;; catégorie 2, sous catégorie 2). Ne demandez pas pourquoi, c'est comme ça. Il faudra donc affecter les données à la main. Il est évident qu'il faudra récupérer l'id de la catégorie avant de faire une insertion. Quand à l'affectation de l'identifiant de la sous-catégorie, on peut utiliser la requête (écrite sous la forme d'une requête paramétrée Java)&amp;nbsp;:&lt;/p&gt;

&lt;pre class=&quot;sql&quot;&gt;&lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;SELECT&lt;/span&gt; MAX&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;id&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;FROM&lt;/span&gt; souscategorie &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;WHERE&lt;/span&gt; idcategorie &lt;span style=&quot;color: #66cc66;&quot;&gt;=&lt;/span&gt; ?&lt;/pre&gt;


&lt;p&gt;ce qui fait que nous pouvons proposer la requête suivante pour une insertion&amp;nbsp;:&lt;/p&gt;

&lt;pre class=&quot;sql&quot;&gt;&lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;INSERT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;INTO&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;`souscategorie`&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;`idcategorie`&lt;/span&gt;, &lt;span style=&quot;color: #ff0000;&quot;&gt;`id`&lt;/span&gt;, &lt;span style=&quot;color: #ff0000;&quot;&gt;`libelle`&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;VALUES&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;?, &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;SELECT&lt;/span&gt; MAX&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;id&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;FROM&lt;/span&gt; souscategorie &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;WHERE&lt;/span&gt; idcategorie &lt;span style=&quot;color: #66cc66;&quot;&gt;=&lt;/span&gt; ?&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; + &lt;span style=&quot;color: #cc66cc;&quot;&gt;1&lt;/span&gt;, ?&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/pre&gt;


&lt;p&gt;Sauf qu'il y a des cas où cette requête ne marche pas... S'il s'agit d'ajouter une sous-catégorie à une catégorie qui n'a pas encore de sous-catégorie, le &lt;em&gt;SELECT&lt;/em&gt; rend un beau &lt;em&gt;NULL&lt;/em&gt;. Aie...&lt;/p&gt;


&lt;p&gt;Alors évidemment, on peut laisser l'applicatif gérer le &lt;em&gt;select&lt;/em&gt; et agir en fonction, mais cela alourdit le code applicatif et provoque deux appels à la base. On peut aussi utiliser certaines fonctions SQL propres à la base pour réaliser cette action. Ici, nous utiliserons la fonction &lt;strong&gt;IFNULL&lt;/strong&gt;. La signature de cette fonction est &lt;em&gt;IFNULL(expr1, expr2)&lt;/em&gt;. Si &lt;em&gt;expr1&lt;/em&gt; n'est pas &lt;em&gt;null&lt;/em&gt;, &lt;em&gt;IFNULL&lt;/em&gt; renvoi &lt;em&gt;expr1&lt;/em&gt;, sinon elle renvoie &lt;em&gt;expr2&lt;/em&gt;. Et bien voila notre solution&amp;nbsp;:&lt;/p&gt;

&lt;pre class=&quot;sql&quot;&gt;&lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;INSERT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;INTO&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;`souscategorie`&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;`idcategorie`&lt;/span&gt;, &lt;span style=&quot;color: #ff0000;&quot;&gt;`id`&lt;/span&gt;, &lt;span style=&quot;color: #ff0000;&quot;&gt;`libelle`&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;VALUES&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;?, &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;IFNULL&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;SELECT&lt;/span&gt; MAX&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;id&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;FROM&lt;/span&gt; souscategorie &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;WHERE&lt;/span&gt; idcategorie &lt;span style=&quot;color: #66cc66;&quot;&gt;=&lt;/span&gt; ?&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;, &lt;span style=&quot;color: #cc66cc;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; + &lt;span style=&quot;color: #cc66cc;&quot;&gt;1&lt;/span&gt;, ?&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/pre&gt;


&lt;p&gt;Dans ce cas, s'il n'y a pas encore de sous-catégorie pour la catégorie voulue (le &lt;em&gt;select&lt;/em&gt; renvoi &lt;em&gt;null&lt;/em&gt;), la fonction &lt;em&gt;IFNULL&lt;/em&gt; renverra 0 et nous aurons notre premier identifiant qui vaudra 1.&lt;/p&gt;


&lt;p&gt;A noter que &lt;strong&gt;IFNULL&lt;/strong&gt; est spécifique à MySQL. Sous Oracle ou Informix, il s'agit de la fonction &lt;strong&gt;NVL&lt;/strong&gt;.&lt;/p&gt;


&lt;h3&gt;En conclusion&lt;/h3&gt;

&lt;p&gt;Il n'y a aucune haute voltige dans ce qui est présenté ici. Malheureusement, ce sont des situations souvent observées dans beaucoup de projets de gestion. Dans ce domaine, tout projet fait intervenir un applicatif et une base de données. Mais on observe bien souvent que le développement de la base de données se limite à définir les tables, leurs clefs primaires, leurs clefs étrangères et leurs indexs. Dans ces contextes, les contraintes d'intégrité référentielle sont gérées au niveau applicatif. La conséquence est évidente aussi bien en terme d'intégrité des données qui ne peut être assurée en fonction du type d'intervention, mais potentiellement en terme de coût de développement. Les SGBD sont aujourd'hui assez riches pour s'occuper aussi bien du stockage des données que d'assurer leur qualité. Lors du design de vos bases, n'hésitez pas à explorer les possibilités du SGBD.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.netapsys.fr/index.php/post/2009/03/12/Integrite-referentielle-et-utilisation-de-fonctions-SQL-ou-comment-rendre-au-SGBD-une-partie-de-ses-responsabilites#comment-form</comments>
      <wfw:comment>http://blog.netapsys.fr/index.php/post/2009/03/12/Integrite-referentielle-et-utilisation-de-fonctions-SQL-ou-comment-rendre-au-SGBD-une-partie-de-ses-responsabilites#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.netapsys.fr/index.php/feed/rss2/comments/77</wfw:commentRss>
      </item>
    
</channel>
</rss>