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

MS SQL Server Discussion :

[SQL Server 2005] Curseur : ordre des instructions


Sujet :

MS SQL Server

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    381
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 381
    Par défaut [SQL Server 2005] Curseur : ordre des instructions
    Bonjour,

    j'ai le problème suivant :
    J'ai un curseur, et dans mon WHILE sur le @@FETCH_STATUS, j'execute une instruction INSERT
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    FETCH CursInstruction INTO @Temp
     
    WHILE @@FETCH_STATUS = 0
    BEGIN
      INSERT INTO ##SCRIPT VALUES (@Temp)
      FETCH NEXT FROM CursInstruction INTO @Temp
    END
    Or je remarque que les Insert ne se font pas dans l'ordre. Quand la variable @Temp (de type VARCHAR(MAX)) contient un volume important, son insertion se fait parfois avec 3 ou 4 occurences de retard.
    Ca me donne donc quelque chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    FETCH met la valeur Instruction1 dans @Temp
    INSERT INTO ##SCRIPT VALUES(Instruction1)
    FETCH met la valeur Instruction2 dans @Temp
    FETCH met la valeur Instruction3 dans @Temp
    INSERT INTO ##SCRIPT VALUES(Instruction3)
    FETCH met la valeur Instruction4 dans @Temp
    INSERT INTO ##SCRIPT VALUES(Instruction2)
    etc...

    Y'a-t-il une solution pour forcer les insert à attendre la fin de l'insert précédent pour s'executer ?

    Merci d'avance !

  2. #2
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    616
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Luxembourg

    Informations forums :
    Inscription : Mars 2007
    Messages : 616
    Par défaut
    Comment tu fais pour afficher ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    FETCH met la valeur Instruction1 dans @Temp
    INSERT INTO ##SCRIPT VALUES(Instruction1)
    FETCH met la valeur Instruction2 dans @Temp
    FETCH met la valeur Instruction3 dans @Temp
    INSERT INTO ##SCRIPT VALUES(Instruction3)
    FETCH met la valeur Instruction4 dans @Temp
    INSERT INTO ##SCRIPT VALUES(Instruction2)
    Et c'est quoi ##Script, c'est une table?

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    381
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 381
    Par défaut
    Oui, c'est une table (temporaire).
    En fait je n'affiche pas, c'est juste en faisant un select * dans ma table ##SCRIPT (qui ne contient qu'une colonne), mes instructions ne sont pas dans l'ordre. Alors que si je ne m'abuse, le select devrait par défaut renvoyer les lignes ordonnées par date d'insertion dans la table, non ?

  4. #4
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    616
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Luxembourg

    Informations forums :
    Inscription : Mars 2007
    Messages : 616
    Par défaut
    Citation Envoyé par nox75 Voir le message
    Oui, c'est une table (temporaire).
    En fait je n'affiche pas, c'est juste en faisant un select * dans ma table ##SCRIPT (qui ne contient qu'une colonne), mes instructions ne sont pas dans l'ordre. Alors que si je ne m'abuse, le select devrait par défaut renvoyer les lignes ordonnées par date d'insertion dans la table, non ?
    C'est faux !! Avec une colonne et sans index cluster tout sera dans le désordre.
    Pour que tes lignes apparaissent dans l'ordre il faut 2 colonnes.

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    381
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 381
    Par défaut
    J'ai ajouté une colonne, le problème reste le même.
    Sinon tant pis j'ajoute une colonne que j'incrémente à chaque insert, et j'order by dessus dans mon select : /

  6. #6
    Membre chevronné Avatar de agemis31
    Profil pro
    DBA
    Inscrit en
    Octobre 2007
    Messages
    399
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : DBA

    Informations forums :
    Inscription : Octobre 2007
    Messages : 399
    Par défaut
    Bonjour,

    A mon humble avis, index ou pas, il faut trier.

    @+

  7. #7
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    616
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Luxembourg

    Informations forums :
    Inscription : Mars 2007
    Messages : 616
    Par défaut
    Citation Envoyé par agemis31 Voir le message
    Bonjour,

    A mon humble avis, index ou pas, il faut trier.

    @+
    Lorsqu'on fait un SELECT * FROM matable les lignes n'apparaissent pas dans l'ordre cluster?
    Il fait pourtant bien un Clustered index scan ?!

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    381
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 381
    Par défaut
    Ben c'est ce que je pensais aussi

  9. #9
    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 : 44
    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,

    Une première chose : en SQL l'ordre n'existe pas, ni pour les lignes, ni pour les colonnes.

    La table (temporaire ou pas) de Nox75 n'étant pas indexée en cluster, les lignes sont donc retournées dans l'ordre de leur insertion.
    Si la table est ordonnée en cluster, alors les lignes sont retournées dans l'ordre physique de la valeur de la clé qui compose l'index cluster.

    Si nous exécutons :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    CREATE TABLE #TEST
    (
    	chaine VARCHAR(50)
    )
     
    INSERT INTO #TEST VALUES ('A')
    INSERT INTO #TEST VALUES ('C')
    INSERT INTO #TEST VALUES ('B')
    INSERT INTO #TEST VALUES ('D')
     
    SELECT *
    FROM #TEST
    Nous avons bien :
    A
    C
    B
    D
    Si à la suite de ce lot nous exécutons :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    TRUNCATE TABLE #TEST
     
    CREATE CLUSTERED INDEX IXC_TEST_chaine
    ON #TEST (chaine)
     
    INSERT INTO #TEST VALUES ('A')
    INSERT INTO #TEST VALUES ('C')
    INSERT INTO #TEST VALUES ('B')
    INSERT INTO #TEST VALUES ('D')
     
    SELECT *
    FROM #TEST
    Nous obtenons :

    A
    B
    C
    D
    Enfin les curseurs peuvent globalement être évités en les remplaçant par des traitements ensemblistes.
    Vous pourrez voir ici la différence en vitesse de traitement.

    Nox75, quelle requête SELECT exécutez-vous pour lire votre table de trace ?

    @++

  10. #10
    Membre chevronné Avatar de agemis31
    Profil pro
    DBA
    Inscrit en
    Octobre 2007
    Messages
    399
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : DBA

    Informations forums :
    Inscription : Octobre 2007
    Messages : 399
    Par défaut
    Bonjour,

    Ma réponse n'était pas claire Je voulais juste dire que si l'on veut un résultat ordonné, il faut le demander, usuellement à l'aide d'un ORDER BY, ce qui à l'avantage d'être déclaratif et lisible.
    Que SQL Serveur renvoie les lignes d'une table possédant un index clustered dans l'ordre de l'index si on omet de trier me semble résulter plus d'une logique d'efficacité que d'une règle.

    Un petit lien intéressant sur ce sujet.

    @+

  11. #11
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    381
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 381
    Par défaut
    Citation Envoyé par elsuket Voir le message
    Nox75, quelle requête SELECT exécutez-vous pour lire votre table de trace ?
    Un simple "select * from ##Script"
    D'après vos réponses, j'en déduis que mon select me renvoie bien les lignes dans l'ordre d'insertion. J'en conclue donc qu'écrire :
    Insert into ##Script values (@var1)
    Insert into ##Script values (@var2)
    Insert into ##Script values (@var3)
    ne garantit pas qu'on aura en table l'ordre @var1, @var2, @var3, si les variables ne contiennent pas la même quantité d'information.
    Si @var1 contient 2000 caractères, et si @var2 n'en contient que 2 ou 3, il est possible que l'insertion de @var1 mette plus de temps, et que @var1 apparaîsse APRES @var2 dans la table.

    Vrai ?

  12. #12
    Membre chevronné Avatar de agemis31
    Profil pro
    DBA
    Inscrit en
    Octobre 2007
    Messages
    399
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : DBA

    Informations forums :
    Inscription : Octobre 2007
    Messages : 399
    Par défaut
    Bonjour nox75,

    D'après vos réponses, j'en déduis que mon select me renvoie bien les lignes dans l'ordre d'insertion
    Je me demande bien comment vous arrivez à en déduire ça!
    Le curseur est procédural et synchrone. Il faut distinguer l'ordre d'insertion, temporel, forcément, puisque vous ajoutez une ligne à la fois via votre curseur, et l'ordre de restitution. Il n'y a pas d'ordre de restitution par défaut quand on requête une table.

    @+

  13. #13
    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 : 44
    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
    Votre table n'étant pas très volumineuse, il est bizarre que les lignes ne vous soient pas retournées dans l'ordre de leur insertion.
    Effectueriez-vous des DELETE sur cette table ? parce que si tel est le cas, l'espace libéré par un tel ordre est réutilisé pour des insertions futures si la table n'est pas clusterisée.

    La solution directe à votre problème, c'est d'ajouter à votre table temporaire une colonne avec la propriété de compteur, puis de la requêter en écrivant ORDER BY maColonneCompteur.

    La vraie solution, c'est de n'utiliser ni les tables temporaires, ni les curseurs

    @++

  14. #14
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    381
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 381
    Par défaut
    Citation Envoyé par agemis31 Voir le message
    Bonjour nox75,



    Je me demande bien comment vous arrivez à en déduire ça!
    Le curseur est procédural et synchrone. Il faut distinguer l'ordre d'insertion, temporel, forcément, puisque vous ajoutez une ligne à la fois via votre curseur, et l'ordre de restitution. Il n'y a pas d'ordre de restitution par défaut quand on requête une table.

    @+
    Je me basais sur la réponse de Elsuket, un peu plus haut. D'après cette réponse, l'ordre par défaut d'un select correspond bien à l'ordre d'insertion dans la table. Ou alors je n'ai rien compris : /
    Citation Envoyé par elsuket Voir le message
    Votre table n'étant pas très volumineuse, il est bizarre que les lignes ne vous soient pas retournées dans l'ordre de leur insertion.
    Effectueriez-vous des DELETE sur cette table ? parce que si tel est le cas, l'espace libéré par un tel ordre est réutilisé pour des insertions futures si la table n'est pas clusterisée.

    La solution directe à votre problème, c'est d'ajouter à votre table temporaire une colonne avec la propriété de compteur, puis de la requêter en écrivant ORDER BY maColonneCompteur.

    La vraie solution, c'est de n'utiliser ni les tables temporaires, ni les curseurs

    @++
    Je ne fais pas de delete, uniquement des insert.
    Je pourrai envoyer la procédure complète demain si vous le souhaitez. J'ai résolu le problème avec une colonne compteur, effectivement, mais je serai tout de meme curieux de connaître la cause de ce problème.
    C'est une procédure qui génère un script de mise à jour des procédures stockées/fonctions/triggers/vues d'une base.

  15. #15
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 022
    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 : 22 022
    Billets dans le blog
    6
    Par défaut
    Je me basais sur la réponse de Elsuket, un peu plus haut. D'après cette réponse, l'ordre par défaut d'un select correspond bien à l'ordre d'insertion dans la table. Ou alors je n'ai rien compris : /
    Erreur : Il n'y a JAMAIS de garantie d'ordre sans clause ORDER BY !

    Relisez le post que j'ai écrit à ce sujet : http://blog.developpez.com/sqlpro/p5...sont-des-ense/

    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/ * * * * *

  16. #16
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    381
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 381
    Par défaut
    Merci SQLPro

    je suis en pleine relecture, mais ce que je don't get, c'est que je retrouve partout cette idée qu'avec une table simple (une seule colonne, pas de clé, pas d'index etc...) et juste des insert (aucun delete), le select renvoie les lignes dans l'ordre d'insertion. C'était je crois le sens du post d'elsuket, et c'est ce que je retrouve dès le début de ton exemple ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    SELECT C, D FROM T_LIGNES 
     
    C           D 
    ----------- ---------------- 
    1           Z                
    2           Y                
    3           X                
    4           W                
    5           V          
     
    Apparament les lignes sont dans l'ordre d'insertion
    C'est donc un pur hasard ?
    Il serait donc possible de reprendre exactement le premier exemple tout à fait basique de votre post explicatif, et d'obtenir un select renvoyant les lignes dans un ordre différent ?

    Si non, pourquoi est-ce que je n'obtiens pas ce résultat dans mon cas ?

  17. #17
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 022
    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 : 22 022
    Billets dans le blog
    6
    Par défaut
    C'est donc un pur hasard ?
    Oui. Même si en pratique dans 95% des cas SQL Server renverra les données dans l'ordre d'insertion, vous ne pouvez ni devez compter sur cela !

    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/ * * * * *

  18. #18
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    381
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 381
    Par défaut
    Ok !

    Ce point est donc réglé, j'utilise une colonne compteur et j'ajoute un Order by dans ma requête.

    Merci à tous pour votre aide et vos explications

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

Discussions similaires

  1. SQL Server 2005 et utilisation des indexes ou autres
    Par orafrance dans le forum Développement
    Réponses: 3
    Dernier message: 02/09/2010, 10h10
  2. [SQL Server 2005 [Express]] récupérer des données
    Par le_ben dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 30/08/2007, 18h11
  3. [SQL Server 2005] DELETE sur des doublons
    Par Shakta dans le forum MS SQL Server
    Réponses: 10
    Dernier message: 16/05/2007, 12h13
  4. [Sql server 2005] Comment faire des taches planifiées?
    Par critok dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 31/05/2006, 13h19
  5. [SQL server 2005 express] liste des erreurs SQL serveur 2005
    Par critok dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 02/05/2006, 20h17

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