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

Développement SQL Server Discussion :

procédure Stocké compliquée pour moi


Sujet :

Développement SQL Server

  1. #1
    Membre confirmé
    Inscrit en
    Septembre 2006
    Messages
    179
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 179
    Par défaut procédure Stocké compliquée pour moi
    Bonjour,
    j'ai deux tables:
    - table_ancien =id, pays, partner, produit, annee, echange(prend les valeurs Import ou Export), valeur
    - table_nouvelle =id, pays, partner, produit, annee, Import, Export

    Ce que je veux faire c'est transferé le contenu de la table table_ancien vers la table table_nouvelle.
    Si vous avez des idées je suis preneur

    Maintenant ce que j'ai fais c'est transferé d'abord les enregistrements avec la valeur Export dans la champ echange grace à la requete suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    insert into table_nouvelle (id, pays, partner, produit, annee, Export)
    select id, pays, partner, produit, annee, valeur
    from table_ancien
    where id='id_pays' and echange='Export'
    Après cette requete le champ Export à une valeur et le champ Import prend la valeur Null.

    Et ce que je dois faire après c'est transferé les données des Imports aussi sachant que j'ai deux cas : soit le pays existe déja avec le même produit et année, dans ce cas je dois faire un Update dans la table_nouvelle en changeant la valeur Null du champ Import par par la nouvelle valeur, et si la nouvelle entrée ne correspond pas un pays avec le meme produit et année existants on va tout simplement l'ajouter avec un Insert.

    J'ai donc pensé à une procédure stocké mais ça dépasse mes compétences.
    Merci de votre aide

  2. #2
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Par défaut
    Bonjour,

    - table_ancien =id, pays, partner, produit, annee, echange(prend les valeurs Import ou Export), valeur
    - table_nouvelle =id, pays, partner, produit, annee, Import, Export

    Ce que je veux faire c'est transferé le contenu de la table table_ancien vers la table table_nouvelle.
    Je ne crois pas que vous ayez fait le bon choix de modélisation.
    La structure de la table table_ancien me semble plus correcte.

    Et ce que je dois faire après c'est transferé les données des Imports aussi sachant que j'ai deux cas : soit le pays existe déja avec le même produit et année, dans ce cas je dois faire un Update dans la table_nouvelle en changeant la valeur Null du champ Import par par la nouvelle valeur, et si la nouvelle entrée ne correspond pas un pays avec le meme produit et année existants on va tout simplement l'ajouter avec un Insert.

    J'ai donc pensé à une procédure stocké mais ça dépasse mes compétences.
    Une procédure stockée est conçue pour être réutilisée plusieurs fois, particulièrement de façon automatique, comme un appel par une application.
    Je pense que vous n'allez changer votre modèle qu'une seule fois, donc il n'y a pas besoin d'écrire une procédure stockée.

    Voici donc les deux requêtes dont vous auriez besoin :

    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
    21
    22
    23
    UPDATE		dbo.table_nouvelle
    SET		Import = TA.valeur
    FROM		dbo.table_nouvelle AS TN
    INNER JOIN	dbo.table_ancienne AS TA
    			ON TN.produit = TA.produit
    			AND TN.pays = TA.pays
    			AND TN.annee = TA.annee
     
    INSERT INTO	dbo.table_nouvelle
    SELECT		id
    		, pays
    		, partner
    		, produit
    		, annee
    		, valeur
    FROM		dbo.table_ancien AS TA
    LEFT JOIN	dbo.table_nouvelle AS TN	
    			ON TN.produit = TA.produit
    			AND TN.pays = TA.pays
    			AND TN.annee = TA.annee
    WHERE		TN.produit IS NULL
    AND		TN.pays IS NULL
    AND		TN.annee IS NULL
    Si vous êtes sous SQL Server 2008, vous pouvez utiliser l'instruction MERGE pour faire les deux en une seule instruction.

  3. #3
    Membre confirmé
    Inscrit en
    Septembre 2006
    Messages
    179
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 179
    Par défaut
    Bonjour et Merci pour votre réponse,
    Au fait je suis complettement d'accord avec vous sur vos remarques concernant la modélisation et l'utilisation des procédures stockés.
    Pour la structure, ce qui m'a poussé à changer l'ancienne par celle là c'est que j'ai des milliers de lignes et quand je fais la recherche ça prend beaucoup de temps et que après je dois faire le calcul de la balance (Export-Import) pour chaque pays,produit,année pour l'afficher via asp.net ce qui complique encore la tâche puisque je suis débutant là aussi ^^, Alors je me suis dis vaut mieu que je fasse le gros travail sur SqlServer en ajoutant aussi le champ "balance" a la nouvelle table et après il ne me reste plus que l'affichage. Mais je dois revoir ça

    Pour la requete que vous m'avez donner j'ai mis celle là et ça ne change aucune ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    update table_nouvelle set Import=valeur 
    from table_ancienne TA, table_nouvelle TN
     where TN.produit = TA.produit AND TN.pays = TA.pays AND TN.annee = TA.annee
    je crois que c'est normal, parcequ'on ne spécifie pas les enregistrement qui doivent etre changer.

    Pourquoi j'ai pensé à une procédure stocker parceque à mon avis y'a qu'avec elle qu'on peut suivre les étapes suivantes :

    - il faut d'abord commencer par la selection des enregistrements qu'on la valeur Import dans la table_ancienne.
    - On parcours cette selection si les procédure stockés dispose d'une fonction "While"
    - on fait le teste grace à "If" pour vérifier si l'enregistrement en cours dans while existe dans la table_nouvelle
    - s'il existe on fait un update du champ Import et si non on ajoute un nouveau enregistrement

    NB: je suis sous SQL SERVER 2000

    Merci

  4. #4
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Par défaut
    Pour la structure, ce qui m'a poussé à changer l'ancienne par celle là c'est que j'ai des milliers de lignes et quand je fais la recherche ça prend beaucoup de temps
    Dans ce cas faites une table qui contient le type de "mouvement" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREATE TABLE tb_import_export
    (
    	import_export_id BIT NOT NULL CONSTRAINT PK_tb_import_export PRIMARY KEY
    	, import_export_nom varchar(8) NOT NULL CONSTRAINT UQ_tb_import_export__import_export_nom UNIQUE (import_export_nom)
    )
    GO
    Il vous suffit ensuite de référencer cette table :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    INSERT INTO dbo.tb_import_export
    (
    	import_export_id
    	, import_export_nom
    )
    SELECT	0, 'Import'
    UNION ALL SELECT 1, 'Export'
    GO
     
    ALTER TABLE maTable
    ADD import_export_id BIT NOT NULL CONSTRAINT FK_tb_import_export__import_export_id
    	FOREIGN (import_export_id) REFERENCES dbo.tb_import_export
    GO
    Désormais vous pouvez faire une jointure en filtrant le type, ou bien filtrer directement la table

    après je dois faire le calcul de la balance (Export-Import) pour chaque pays,produit,année pour l'afficher via asp.net ce qui complique encore la tâche puisque je suis débutant là aussi ^^, Alors je me suis dis vaut mieu que je fasse le gros travail sur SqlServer en ajoutant aussi le champ "balance" a la nouvelle table et après il ne me reste plus que l'affichage
    Vous pouvez donc en faire une vue, et requêter la vue soit par une procédure stockée, soit directement depuis votre page ASP.NET.

    Pour la requete que vous m'avez donner j'ai mis celle là et ça ne change aucune ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    UPDATE table_nouvelle SET Import=valeur 
    FROM table_ancienne TA, table_nouvelle TN
     WHERE TN.produit = TA.produit AND TN.pays = TA.pays AND TN.annee = TA.annee
    Comme vous n'avez pas qualifié la colonne valeur par l'alias de la table de laquelle vous voulez le "copier", je vous laisse deviner la suite
    J'ai comme habitude de codage de toujours qualifier les colonnes par l'alias de la table à laquelle elles appartiennent, et les tables par le nom du schéma auquel elles appartiennent.
    Cela m'évite des déconvenues visiblement

    Pourquoi j'ai pensé à une procédure stocker parceque à mon avis y'a qu'avec elle qu'on peut suivre les étapes suivantes :

    - il faut d'abord commencer par la selection des enregistrements qu'on la valeur Import dans la table_ancienne.
    - On parcours cette selection si les procédure stockés dispose d'une fonction "While"
    - on fait le teste grace à "If" pour vérifier si l'enregistrement en cours dans while existe dans la table_nouvelle
    - s'il existe on fait un update du champ Import et si non on ajoute un nouveau enregistrement
    En SQL, par de curseurs, pas de WHILE.
    SQL est un langage ensembliste, et il n'est pas conçu pour traiter les données ligne-à-ligne, ce pourquoi d'ailleurs il est particulièrement contre-performant.
    Cherchez RBAR sur votre moteur de recherche préféré, et bonne lecture

    En ce sens le type de requête que je vous ai donné doit fonctionner correctement et bien plus rapidement que ligne à ligne.

    La procédure stockée vous permet de sauvegarder un batch comme un objet de base de données.
    Lors de la première exécution de celle-ci un plan est généré et conservé dans le cache de plans.
    Pour faire simple, la durée de conservation dans le cache de plan est proportionnel au nombre d'utilisations de la procédure.

    Comme vous n'allez pas changer de structure de données, vous n'avez aucun intérêt à écrire une procédure stockée.
    Sauvegardez en revanche pieusement le script qui vous a permis de passer d'une structure de données à l'autre.

    Enfin SQL Server 2000 est, comme son nom l'indique, vieux de 10 ans.
    Le moteur de bases de données ayant été sévèrement amélioré au passage à la version 2005, je ne peux que vous conseiller de passer à la version 2008.
    En édition Express (gratuite), vous pouvez gérer jusqu'à 10GB de données

    @++

Discussions similaires

  1. Une requête bien compliquée pour moi
    Par bellande dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 01/02/2007, 21h51
  2. Requete un peu compliqué pour moi
    Par passie dans le forum Langage SQL
    Réponses: 4
    Dernier message: 27/04/2006, 15h08
  3. [SQL - ORACLE] Requete un peu compliquée (pour moi)
    Par Worldofdada dans le forum Langage SQL
    Réponses: 15
    Dernier message: 03/11/2005, 08h25
  4. Requête un peu trop compliqué pour moi
    Par Kokito dans le forum Langage SQL
    Réponses: 5
    Dernier message: 18/04/2005, 15h17
  5. Réponses: 3
    Dernier message: 09/09/2004, 11h31

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