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

SQL Firebird Discussion :

CREATE TABLE + COMPUTED BY


Sujet :

SQL Firebird

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé

    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    502
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 502
    Par défaut CREATE TABLE + COMPUTED BY
    Bjr

    la doc IB fait allusion à une clause COMPUTED BY dans la définition des champs d'une table. Le code suivant exécute via FlameRobin vers un serveur FB déclenche pourtant un erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    create table TEST
    (
    A integer COMPUTED (select sum(B) from TEST),
    B integer not NULL
    );
    Erreur :

    Engine Code : 335544569
    Engine Message :
    Dynamic SQL Error
    SQL error code = -104
    Token unknown - line 4, char 4
    select

  2. #2
    Membre Expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Par défaut
    c'est possible si :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    COMPUTED BY ((SELECT ...))
    mais franchement c'est suicidaire

  3. #3
    Membre Expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 052
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 052
    Par défaut

  4. #4
    Membre éclairé

    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    502
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 502
    Par défaut
    Citation Envoyé par makowski Voir le message
    c'est possible si :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    COMPUTED BY ((SELECT ...))
    mais franchement c'est suicidaire
    Ah bon, et pourquoi ? Il ne s'agit pas de faire des calculs sur des milliers de lignes...

    Enfin merci, je vais essayer.

  5. #5
    Membre éclairé

    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    502
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 502
    Par défaut
    En effet ça fonctionne, encore merci.

    Je trouve que c'est une alternative élégante à la création d'un trigger qui fait un calcul dans l'évenement insert,update ou delete d'une table. L'inconvénient est que l'évaluation du champ calculé se fait même à la lecture mais le tout est d'être raisonnable quand au volume du calcul demandé.

    Comme dit le proverbe "un couteau n'est ni vrai ni faux, mais celui qui l'empoigne par la lame est dans l'erreur"

  6. #6
    Membre Expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 052
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 052
    Par défaut
    Si la table ne contiendra jamais plus de quelques enregistrements, pourquoi pas...

    Mais de là à dire que c'est une manière élégante je ne suis pas d'accords

    Personnellement je ne ferais pas comme ça, ma table ne contiendrait que la colonne B.

    Car A n'apporte rien (il a la même valeur quelque soit la ligne lue) et surtout si un jour votre table contient beaucoup d'enregistrements une simple lecture deviendra vite catastrophique.

    Il n'y a qu'à voir en remplissant avec seulement 1000 enregistrements si on veut lire cette table FB devra effecter 1000*1000+1000= 1 001 000 de lectures.

    Plus d'un million de lecture !!!

    Si vous ne voulez pas faire 2 requetes depuis le client (une pour le select sum(B) from test) et une pour le select B from Test, vous pouvez faire une procédure stoquée :

    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
    18
    19
    20
    SET TERM ^ ;
     
    CREATE PROCEDURE PS_TEST
    RETURNS (
        A integer, 
        B INTEGER)
    AS
    BEGIN
     select sum(b) from test 
       into :a;
      FOR
        select b  from test
        INTO :B
      DO
      BEGIN
        SUSPEND;
      END
    END^
     
    SET TERM ; ^
    un simple select A, B from PS_TEST; sera bien plus performant. (1000+1000=2000 lectures)

    Ou autre solution créer une vue :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CREATE VIEW V_TEST(
        A)
    AS
    select sum(B)
    from TEST;
    Puis un

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    select V.A,  T.B
    from TEST T, V_TEST V;
    Vous retournera le résultat. Avec les mêmes performances que la procédure stoquée.

    PS : LA solution du trigger n'est pas terrible non plus car d'une celà vous oblique à stoquer le champ A et de deux à chaque Insert/update sur la table vous aller devoir mettre à jours TOUS les enregistrements de la table. Celà va donc faire baisser les perfs des inserts/updates et surtout sera une grosse contrainte en terme d'accès concurrentiels...

    Barbibulle

  7. #7
    Membre éclairé

    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    502
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 502
    Par défaut
    Tout ça est vrai.

    Toutefois l'exemple donné était assez trivial pour aller vite.

    Il est certain qu'avec une formule du type sum(a) c'est un peu idiot car en effet on aura la même valeur dans toutes les lignes. Mais imaginez que la table soit celle des clients (Table T1) et que l'on souhaite obtenir le montant des factures (table T2) adressées à ces clients. Alors la formule sera un select sum (T2.montant) from T2 where T1.id_client = t2.id_client.

    La CPU consommée est plus modeste, on fait l'économie d'un trigger (et d'une vue). La CPU est consommée quand on a besoin de lire et non quand on écrit dans T2.

    Tout dépend de la fréquence relative des écritures et des lectures...

Discussions similaires

  1. CREATE TABLE .... AS SELECT
    Par blids dans le forum SQL
    Réponses: 5
    Dernier message: 13/10/2016, 14h00
  2. create table
    Par boucher_emilie dans le forum ASP
    Réponses: 3
    Dernier message: 08/07/2004, 17h08
  3. [DB2] create table... if not exists ?
    Par iubito dans le forum DB2
    Réponses: 6
    Dernier message: 23/03/2004, 18h26
  4. Create table + jointure
    Par ender999 dans le forum Débuter
    Réponses: 7
    Dernier message: 20/02/2004, 12h04
  5. Database new user & create table
    Par MFDev dans le forum InterBase
    Réponses: 3
    Dernier message: 30/09/2003, 20h47

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