IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage SQL Discussion :

Intégrité référentielle et/ou Intégrité de domaine


Sujet :

Langage SQL

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 128
    Points : 70
    Points
    70
    Par défaut Intégrité référentielle et/ou Intégrité de domaine
    Bonjour,

    Imaginons que nous ayons 3 tables A, B et C. La table A et B ont une clé primaire chacune(de type int) et des champs quelconques.
    La table C est une relation entre la table A et B. Elle contient 2 champs, des clés étrangères. La première clé étrangère fait référence à la clé primaire de la table A, et la deuxième clé étrangère à la table B.

    Ma question : Si j'ajoute une ligne à ma table C, disons : (50, 40), mais que 50 n'est pas une valeur contenue dans le champ de la clé primaire de la table A, s'agit-il d'une violation de l’intégrité référentielle ou de l'intégrité de domaine ?

    Sur cette page : http://msdn.microsoft.com/fr-fr/libr...=sql.105).aspx, il est dit :
    L'intégrité de domaine fait référence à la fourchette (au domaine) des entrées valides pour une colonne spécifique.
    Et :
    Lorsque vous mettez en application l'intégrité référentielle, SQL Server interdit aux utilisateurs d'effectuer les opérations suivantes :
    ajouter ou modifier des lignes dans une table connexe lorsqu'il n'y a aucune ligne associée dans la table primaire ;
    Ces deux citations me paraissant équivalentes pour le problème plus haut, je ne sais pas dire quelle intégrité est violée.

    Pourriez-vous éclaircir ma chandelle, svp ?

    Merci

  2. #2
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir zizoufoot,


    Intégrité de domaine

    Considérons l’instruction suivante qui permet de créer la table CLIENT des clients :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CREATE TABLE CLIENT (
             CliId             INT                  NOT NULL
           , CliNom            VARCHAR(48)          NOT NULL
      , CONSTRAINT CLIENT_PK PRIMARY KEY  (CliId)
    ) ;

    En vertu de la contrainte de domaine (aujourd’hui on utilise plutôt contrainte de type, mais peu importe), les valeurs prises par la colonne CliId doivent être des entiers, dans la plage -2^31 à 2^31-1.

    Si vous exécutez l’instruction :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    INSERT INTO CLIENT (CliId, CliNom) VALUES ('a', 'Fernand') ;

    Alors il y a violation de l’intégrité de type (domaine) et SQL Server rejette l’opération :

    « Échec de la conversion de la valeur varchar 'a' en type de données int. »

    De même si vous êtes hors limites :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    INSERT INTO CLIENT (CliId, CliNom) VALUES (111111111111111, 'Fernand') ;
    =>
    « Une erreur de dépassement arithmétique s'est produite lors de la conversion de expression en type de données int. »


    Considérons maintenant l’instruction suivante qui permet de créer la table FACTURE des factures des clients :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE TABLE FACTURE 
    (
             FactId               INT                  NOT NULL
           , CliId                INT                  NOT NULL
           , FactDate             DATE                 NOT NULL
       , CONSTRAINT FACTURE_PK PRIMARY KEY (FactId)
       , CONSTRAINT FACTURE_CLI_FK FOREIGN KEY (CliId) REFERENCES CLIENT (CliId)
    ) ;

    Pour respecter l’intégrité de domaine, les valeurs prises par les colonnes FactId et CliId doivent là aussi être des entiers, dans la plage -2^31 à 2^31-1. Pour sa part, la colonne FactDate doit prendre des valeurs conformes au type DATE. Si vous tentez de fournir la valeur 2013-04-48 pour cette colonne (jour invalide), SQL Server rejettera l’opération et vous aurez droit à un message du genre :
    « La conversion d'un type de données CHAR en type DATE a donné une valeur hors limite de date et d'heure. »


    Intégrité référentielle

    Les tables CLIENT et FACTURE sont liées par la contrainte d’intégrité référentielle FACTURE_CLI_FK selon laquelle la colonne CliId de la table FACTURE fait l’objet de la clé étrangère {CliId} telle que les valeurs de cette colonne soient obligatoirement des valeurs de la colonne CliId de la table CLIENT. Si cette contrainte n’existait pas alors on se retrouverait très facilement avec des factures concernant des clients inconnus : ce ne sont pas les clients concernés qui se plaindront...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 128
    Points : 70
    Points
    70
    Par défaut
    Merci pour ta réponse

    Je pensais exactement comme toi au départ.
    Ensuite, j'ai lu : http://msdn.microsoft.com/fr-fr/libr...=sql.105).aspx et plus exactement :
    L'intégrité de domaine fait référence à la fourchette (au domaine) des entrées valides pour une colonne spécifique. Vous pouvez mettre en application l'intégrité de domaine pour restreindre le type, à l'aide des types de données, le format, à l'aide des contraintes CHECK et des règles, ou la fourchette des valeurs possibles, à l'aide des contraintes FOREIGN KEY et CHECK, des définitions DEFAULT et NOT NULL, et des règles.
    Et moi j'ai interprété cette phrase comme suit : (en reprenant ton exemple)
    Dans la table FACTURE, si on ajoute une ligne dans laquelle la valeur du champ CliId n'est pas une valeur comprise dans l'ensemble {SELECT CliId FROM CLIENT}, alors il y a violation de l'intégrité de domaine.
    Mais au départ, avant de lire la MSDN, j'étais de l'avis de dire qu'il s'agissait d'une violation de l'intégrité de référence. Maintenant, je me dis qu'il y a peut-être aussi violation de l'intégrité de domaine, non ?

    Edit : Je pense que l'erreur provient de ma mauvaise compréhension de la citation du MSDN. Car {SELECT CliId FROM CLIENT} ne renvoi pas de NULL, or une clé étrangère peut être NULL(sauf si contrainte de domaine).

  4. #4
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut Le domaine selon les loufs
    Bonjour zizoufoot,


    Ce que MS SQL Server appelle « DOMAINE » n’est pas un domaine, mais une construction fort bizarre. Je rappelle ce qu’a écrit Ted Codd en 1970 dans son article fondateur A Relational Model of Data Large Shared Data Banks, je cite et traduis :
    « Le terme relation est utilisé ici dans son acception mathématique. Étant donnés les ensembles S1, S2, ..., Sn (non nécessairement distincts), R est une relation sur ces n ensembles si c'est un ensemble de n-uplets, le 1er élément de chacun d'eux tirant sa valeur de S1, le 2e de S2, et ainsi de suite (de manière plus concise, R est un sous-ensemble du produit cartésien S1 X S2 X ... X Sn). On fera référence à Sj comme étant le jième domaine de R. Suite à ce qui vient d'être énoncé, on dit que R est de degré n. Les relations de degré 1 sont souvent dites unaires, celles de degré 2 binaires, de degré 3 ternaires, et celles de degré n n-aires. »
    Le concept de domaine vient donc des mathématiques. Jusqu’au milieu des années quatre-vingt-dix, tous les SGBD SQL (à l’exception de RDB de DEC) on ignoré superbement le concept de domaine, tandis que nous le réclamions invariablement sur l’air des lampions puisqu’il est au coeur de la théorie relationnelle. Et patatras, ceux qui font la norme SQL ont accouché d’un concept dévoyé, décrit dans SQL/92 :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Domain-definition
        ::=    CREATE DOMAIN domain [AS] data-type
                             [default-definition]
                             [domain-constraint-definition-list]

    Où à son tour « domain-constraint-definition-list » se présente ainsi :

    [CONSTRAINT constraint] CHECK (conditional expression)

    Puis, si on tire sur la ficelle, on en arrive aux cas où « conditional expression » peut être en particulier (j’abrège la liste) une condition du type :

    in-condtion

    exists-condition

    C'est-à-dire que l’on peut faire référence à une [expression de] table pour définir ce que la norme prétend être un domaine !

    Je cite et traduis Chris Date (Relational Database, Writings 1991 - 1994, page 104) :

    « Une règle d’intégrité de domaine se contente conceptuellement d’énumérer les valeurs qui composent ce domaine. Néanmoins SQL/92 permet qu’une règle d’intégrité de “domaine” implique une expression à valeur de vérité, de complexité arbitraire. Un pareil laxisme injustifié sème la pagaille au sein de concepts tout à fait fondamentaux. Par exemple, si on définit le domaine D de telle sorte qu’il tire ses valeurs de la colonne C de la table T, alors QUEL EST LE DOMAINE DE LA COLONNE T.C ? Je recommande vivement de ne pas “tirer avantage” de cet aspect tout à fait étrange de SQL/92. »

    A son tour, Microsoft se contente manifestement de suivre ce qui vient de la norme dont la définition du domaine est bonne pour la poubelle, d’où ses recommandations pour le moins étranges, faisant intervenir les clés étrangères, la clause NOT NULL, etc., et qui vous ont fait tiquer à juste titre.


    En complément :

    Je ferai observer que selon la norme, un domaine est défini « [AS] data-type », c'est-à-dire comme un sous-ensemble d’un type de données existant : INTEGER, CHAR, ... : pas moyen de décoller et de définir soi-même un domaine aussi simple que le domaine POINT (en coordonnées cartésiennes ou polaires, peu importe), puis le domaine ELLIPSE, etc. Un domaine n'a pas à faire obligatoirement référence à un data-type du SGBD, on doit pouvoir écrire par exemple (je m’inspire ici de Tutorial D où le terme DOMAIN a été remplacé par celui de TYPE) :
    Code D : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    DOMAIN LONGUEUR ORDINAL    -- domaine des longueurs (ORDINAL signifie que 2 longueurs peuvent être comparées).
        {X RATIONAL CONSTRAINT X >= 0.0} ;
    Où X est le composant du type qui me convient (rationnel en l’occurrence).


    Code D : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    DOMAIN ANGLE ORDINAL
        RHO RATIONAL CONSTRAINT RHO >= 0.0 AND RHO < 3.14159} ;

    Code D : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    DOMAIN POINT    -- points géométriques dans l’espace à 2 dimensions
        POSSREP CARTESIAN {X RATIONAL, Y RATIONAL}
        POSSREP POLAR {R LONGUEUR, THETA ANGLE} ;

    Code D : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    DOMAIN ELLIPSE 
        {A LONGUEUR, B LONGUEUR, CENTRE POINT CONSTRAINT A >= B} ;

    C'est-à-dire qu’on doit pouvoir enfin décoller de façon très simple et ne pas rester scotché au ras des types fournis par le SGBD.
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 128
    Points : 70
    Points
    70
    Par défaut
    Merci pour ta réponse très complète
    Elle me permet de continuer sereinement

  6. #6
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Ce fut un plaisir, rendez-vous à la prochaine légende à détruire

    keep up the good work!
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  7. #7
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 761
    Points : 52 547
    Points
    52 547
    Billets dans le blog
    5
    Par défaut
    1) la contrainte de domaine est très simplement l'ensemble de toutes les valeurs possible de l'attribut considéré.

    2) MS SQL Sever permet la création de conraintes de domaine par le biais de CREATE TYPE + CREATE DEFAULT + CREATE RULE.

    Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    CREATE TYPE dbo.TYP_POURCENT
    FROM FLOAT;
    GO
     
    CREATE DEFAULT dbo.DFT_ZERO 
    AS 0;
    GO
     
    CREATE RULE dbo.RGL_POURCENT
    AS @VALUE BETWEEN 0 AND 100;
    GO
     
    EXEC sp_bindefault 'dbo.DFT_ZERO', 'dbo.TYP_POURCENT';
    GO
     
    EXEC sp_bindrule 'dbo.RGL_POURCENT', 'dbo.TYP_POURCENT';
    GO
    Dès lors vous pouvez utiliser dbo.TYP_POURCENT comme n'importe quel autre type de données.

    CEPENDANT !
    MS considère comme "deprecated" cette fonctionnalité... Et ne propose actuellement rien en remplacement
    Elle ne fonctionne d'ailleurs pas si vous utilisez l'instruction MERGE (à partir de 2008).

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  8. #8
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir,


    Citation Envoyé par SQLpro Voir le message
    La contrainte de domaine est très simplement l'ensemble de toutes les valeurs possible de l'attribut considéré.
    C’est tout à fait exact, on est en phase. Je préciserai en plus qu’un domaine (au sens de Codd bien entendu) est une entité mathématique, et ne se situe donc ni dans le temps ni dans l’espace : MS SQL Server 2005 en cela est conforme parce que les seules valeurs possibles d’un domaine que je crée constituent un sous-ensemble des valeurs fournies par son type de référence (INT, CHAR, DATE, etc.) lequel est fourni par le SGBD et lui seul. De son côté, au lieu de donner le bon exemple, la norme SQL commet un contresens (a great blunder comme diraient Date et Darwen), elle pêche contre l’esprit en permettant de définir un domaine par référence à une colonne de table, alors qu’une table (que j’appellerais volontiers variable de table, vartable) prend évidemment différentes valeurs dans le temps, au fil des INSERT, UPDATE et DELETE. Ça serait un non sens de disposer de ces opérations pour changer dynamiquement les valeurs des domaines.


    Reprenons maintenant l’exemple :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    CREATE TYPE dbo.TYP_POURCENT
    FROM FLOAT;
    Il y a un problème avec cette instruction CREATE TYPE, car le type TYP_POURCENT n’est en réalité qu’un sous-type de FLOAT, donc — question que j'ai déjà posée — comment faire pour pouvoir enfin décoller de façon très simple et ne pas rester scotché au ras des types fournis par le SGBD, comment arriver à créer un type du genre POINT (cf. mon avant-dernier message), avec typage fort (strong typing), c'est-à-dire impossibilité de comparer des points avec autre chose que des points et qui plus est seulement avec l’opérateur de comparaison scalaire « = », le seul en l’occurrence ayant un sens ?
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  9. #9
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 761
    Points : 52 547
    Points
    52 547
    Billets dans le blog
    5
    Par défaut
    1) sur le DOMAINE à la sauce MS, la technique est pas si conne, d'avoir isolé les RULE des "TYPE"s (en fait domaines), parce que l'on peut réutiliser une même "rule" pour plusieurs "type"s ce qui améliore la mise en cache.

    2) il est possible de créer des types hors de ceux définit par le sous ensemble des types SQL, mais cela doit se faire via SQL CLR en .net. Dans ce cas c'est au choix l'assembly (code .net) ou des contraintes SQL dans la table (hélas) qui permet d'encadrer le domaine.
    Un exemple sont les types "geometry" et "geography" codés en .net.
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    CREATE TABLE T_POINT_PNT
    (PNT_ID          INT NOT NULL IDENTITY PRIMARY KEY,
     PNT_POINT       geography CONSTRAINT CK_PNT CHECK(PNT_POINT.STDimension() = 0),
      PNT_NATURE      VARCHAR(16) CHECK (PNT_NATURE IN ('Pompe à essence', 'Radar', 'resto')),
     PNT_DESCRIPTION VARCHAR(256));
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    INSERT INTO T_POINT_PNT VALUES 
    ('POINT(12.34 14.18)', 'Radar', 'Limitation de vitese à 130 km/h')
    Tout va bien...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    -- erreur de domaine, n'est pas un point (STDimension() > 0)
    INSERT INTO T_POINT_PNT VALUES 
    ('POLYGON((-122.358 47.653, -122.348 47.649, -122.348 47.658, -122.358 47.658, -122.358 47.653))', 'Pompe à essence', 'BP')
    Msg*547, Niveau*16, État*0, Ligne*2
    L'instruction INSERT est en conflit avec la contrainte CHECK "CK_PNT". Le conflit s'est produit dans la base de données "tempdb", table "dbo.T_POINT_PNT", column 'PNT_POINT'.
    L'instruction a été arrêtée.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    -- erreur de définition, hors limites (erreur .net)
    INSERT INTO T_POINT_PNT VALUES 
    ('POINT(12345687 1254784)', 'Pompe à essence', 'BP')
    Msg*6522, Niveau*16, État*1, Ligne*2
    Une erreur .NET Framework s'est produite au cours de l'exécution de la routine ou de la fonction d'agrégation définie par l'utilisateur "geography"*:
    System.FormatException: 24201*: les valeurs de latitude doivent être comprises entre -90 et 90*degrés.
    System.FormatException:
    à Microsoft.SqlServer.Types.GeographyValidator.ValidatePoint(Double x, Double y, Nullable`1 z, Nullable`1 m)
    à Microsoft.SqlServer.Types.Validator.BeginFigure(Double x, Double y, Nullable`1 z, Nullable`1 m)
    à Microsoft.SqlServer.Types.ForwardingGeoDataSink.BeginFigure(Double x, Double y, Nullable`1 z, Nullable`1 m)
    à Microsoft.SqlServer.Types.CoordinateReversingGeoDataSink.BeginFigure(Double x, Double y, Nullable`1 z, Nullable`1 m)
    à Microsoft.SqlServer.Types.OpenGisWktReader.ParsePointText(Boolean parseParentheses)
    à Microsoft.SqlServer.Types.OpenGisWktReader.ParseTaggedText(OpenGisType type)
    à Microsoft.SqlServer.Types.OpenGisWktReader.Read(OpenGisType type, Int32 srid)
    à Microsoft.SqlServer.Types.SqlGeography.GeographyFromText(OpenGisType type, SqlChars taggedText, Int32 srid)
    à Microsoft.SqlServer.Types.SqlGeography.Parse(SqlString s)
    .
    L'instruction a été arrêtée.


    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  10. #10
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Ave,


    Si pour définir des types (domaines) — poutres maîtresses de l’édifice —, il faut sortir de SQL, alors on a raté le défi qui est justement de rester au sein du langage, lequel à défaut montrerait ses limites¹.

    Pour reprendre la table CLIENT :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREATE TABLE CLIENT 
    (
             CliId             INT                  NOT NULL
           , CliNom            VARCHAR(48)          NOT NULL
      , CONSTRAINT CLIENT_PK PRIMARY KEY  (CliId)
    ) ;
    J’aimerais bien pouvoir coder :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREATE TABLE CLIENT 
    (
             CliId             CliId                NOT NULL
           , CliNom            VARCHAR(48)          NOT NULL
      , CONSTRAINT CLIENT_PK PRIMARY KEY  (CliId)
    ) ;
    De telle façon que seul l’opérateur de comparaison scalaire « = » soit utilisable pour le type CliId, incompatible bien sûr avec les autres types (INT et compagnie), au nom du typage fort. Sans monter d’usine à gaz, sans devoir faire appel à un autre langage, j’aimerais pouvoir définir ce type à la façon de Tutorial D, en une ligne :

    Code D : Sélectionner tout - Visualiser dans une fenêtre à part
    TYPE CliId POSSREP {C INT CONSTRAINT C > 0} ;

    Une incidente :

    Ne pas rester au sein du langage, ça me rappelle le coup de la machine bases de données Teradata avec ses 128 processeurs (à 1MF le processeur !), il y a de ça près de 20 ans, alors que le SQL de Teradata ne proposait pas l’opérateur UNION (d’où incomplétude du langage au sens de Codd) : pour pallier et effectuer l’opération, soit j’utilisais le connecteur OR mais pour un temps de traitement et une consommation de ressources rédhibitoires, soit j’exportais les tables sur des fichiers à destination de z/OS (MVS à l’époque), où je me contentais de concaténer ces fichiers (coût : 0 sec.) pour les réimporter à destination de la table hébergeant le résultat.


    Histoire de rire un peu, voici un extrait de l’EXPLAIN Teradata concernant l’utilisation du connecteur OR, EXPLAIN que j’ai pieusement conservé :
    [...]

    7) We do an all-AMPs JOIN step from Spool 12 (Last Use) by way of an all-rows scan, which is joined to Spool 13 (Last Use). Spool 12 and Spool 13 are joined using a product join. The result goes into Spool 14, which is built locally on the AMPs. The size of Spool 14 is estimated to be 231 517 982 080 rows. The estimated time for this step is 17 479 hours and 42 minutes.

    8) We do an all-AMPs RETRIEVE step from Spool 14 by way of an all-rows scan with a condition of ("(Spool_14.I01_C_NUMER_ID = Spool_14.I01_C_NUMER_ID) AND ((Spool_14.I01_C_NUMER_ID = Spool_14.I01_C_NUMER_ID) AND (((Spool_14.T59_C_CODE_T59 = 1292) OR (Spool_14.T59_C_CODE_T59 = 1293 )) AND ((NOT (Spool_14.T59_C_CODE_T59 IS NULL )) AND (NOT (Spool_14") into Spool 15, which is redistributed by hash code to all AMPs. The size of Spool 15 is estimated to be 231 517 982 080 rows. The estimated time for this step is 6 794 hours and 5 minutes.

    9) We do an all-AMPs RETRIEVE step from Spool 14 (Last Use) by way of an all-rows scan with a condition of ("(Spool_14.I01_C_NUMER_ID <> Spool_14.I01_C_NUMER_ID) or ((Spool_14.I01_C_NUMER_ID <> Spool_14.I01_C_NUMER_ID) or (((Spool_14.T59_C_CODE_T59 <> 1292) AND (Spool_14.T59_C_CODE_T59 <> 1293 )) OR ((Spool_14.T59_C_CODE_T59 IS NULL) OR (Spool_14.R10_C_COD") into Spool 16, which is built locally on the AMPs. Then we do a SORT to order Spool 16 by row hash. The size of Spool 16 is estimated to be 231 517 982 080 rows. The estimated time is 3 243 hours and 15 minutes.

    10) We do an all-AMPs JOIN step from Spool 16 (Last Use) by way of an all-rows scan, which is joined to Spool 7 (Last Use). Spool 16 and Spool 7 are joined using an exclusion merge join, with a join condition of ("Spool_16.I01_C_NUMER_ID = Spool_7.I01_C_NUMER_ID"). The result goes into Spool 17, which is built locally on the AMPs. Then we do a SORT to order Spool 17 by row hash. The size of Spool 17 is estimated to be 231 517 982 080 rows. The estimated time for this step is 3 243 hours and 15 minutes.

    11) We do an all-AMPs JOIN step from Spool 17 (Last Use) by way of an all-rows scan, which is joined to Spool 6 (Last Use). Spool 17 and Spool 6 are joined using an exclusion merge join, with a join condition of ("Spool_17.I01_C_NUMER_ID = Spool_6.I01_C_NUMER_ID"). The result goes into Spool 15, which is redistributed by hash code to all AMPs. Then we do a SORT to order Spool 15 by the sort key in spool field1 eliminating duplicate rows. The size of Spool 15 is estimated to be 231 517 982 080 rows. The estimated time for this step is 5 092 hours and 46 minutes.

    12) We do an all-AMPs RETRIEVE step from Spool 15 (Last Use) by way of an all-rows scan into Spool 2, which is built locally on the AMPs. The size of Spool 2 is estimated to be [b]173 638 486 560 rows[b]. The estimated time for this step is 1 491 hours and 31 minutes.

    ...
    Édifiant, n’est-ce pas?
    _______________________________________

    ¹ Dans la série Contes et légendes du pays des bases de données, voici un bref extrait de la page 2 de l’ouvrage Bases de données orientées objet, origines et principes, par Véronique Benzaken et Anne Doucet, aux éditions Armand Colin, 1993 :
    « Les systèmes relationnels commencent également à montrer leurs limites en terme de puissance de calcul. Les langages de requêtes, généralement déclaratifs, ne permettent pas d’exprimer tous les traitements. Par exemple, une application classique consistant à gérer des pièces complexes composées de pièces élémentaires et/ou composites peut avoir à effectuer le traitement du calcul du prix de revient d’une pièce (prix de base des pièces élémentaires et coût d’assemblage des pièces composites). Un tel calcul doit s’appliquer récursivement à toutes les pièces intervenant dans la construction d’une pièce donnée. Ceci n’est pas réalisable au moyen de langages tels que SQL. »

    Ted Codd avait déjà traité de la jointure récursive quatorze ans avant que ceci ne fut écrit et avec Chamberlin, SQL n’a pas été en reste...

    Les auteurs pourront aller voir ici ou ou ...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  11. #11
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 761
    Points : 52 547
    Points
    52 547
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par fsmrel Voir le message
    The estimated time for this step is 17 479 hours and 42 minutes.
    The estimated time for this step is 6 794 hours and 5 minutes.
    The estimated time for this step is 3 243 hours and 15 minutes.
    The estimated time for this step is 3 243 hours and 15 minutes.
    The estimated time for this step is 5 092 hours and 46 minutes.
    The estimated time for this step is 1 491 hours and 31 minutes.
    Je ne m'étonne pas maintenant que tu soit si vieux, si tu a patienté si longtemps !!! ;-)

    A +

    PS : note bien que cela ne fait que 4 ans et 2 mois pour traiter ta requête....
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  12. #12
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Je ne m'étonne pas maintenant que tu soit si vieux, si tu a patienté si longtemps !!! ;-)
    [...]
    note bien que cela ne fait que 4 ans et 2 mois pour traiter ta requête....
    Ma patience ayant quand même des limites (tout comme celle de l’utilisateur ), en réalisant l’union sous MVS, un quart d’heure suffisait, ouf !
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Héritage] problème intégrité référentielle
    Par Ouark dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 24/01/2006, 18h47
  2. Réponses: 7
    Dernier message: 06/12/2005, 15h25
  3. Intégrité référentielle entre 2 schémas
    Par Fabien Celaia dans le forum Oracle
    Réponses: 2
    Dernier message: 21/11/2005, 09h51
  4. Réponses: 5
    Dernier message: 26/10/2005, 14h43
  5. Types de tables - Support des Intégrités référentielles
    Par danuz dans le forum SQL Procédural
    Réponses: 6
    Dernier message: 11/12/2004, 15h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo