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

Sybase Discussion :

[ASE] Problème étrange avec une procédure stockée


Sujet :

Sybase

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 12
    Points : 5
    Points
    5
    Par défaut [ASE] Problème étrange avec une procédure stockée
    Bonjour,

    Voici mon problème :
    j'ai une procédure stockée qui permet des mettre à jour un champ dans plusieurs tables.
    Mon problème est que pour certaines tables ça marche sans problème et pour d'autres seules quelques lignes sont traitées et aucune erreur n'est retournée.
    Si je relance la procédure pour ces tables, quelques lignes sont traitées en plus (par exemple, au premier passage, 2 lignes sont traitées, puis 5, puis 10... c'est complètement aléatoire), de sorte que si je lance la procédure assez de fois, toute la table est traitée.

    Est-ce que quelqu'un a déjà eu ce type de problème ? et si oui, d'où cela peut-il venir ?

    Merci

  2. #2
    Membre chevronné

    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 307
    Détails du profil
    Informations personnelles :
    Âge : 64
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 307
    Points : 1 828
    Points
    1 828
    Par défaut
    Est-ce que tu as vérifié la valeur du rowcount ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    set rowcount 0
    go
    Michael
    Michael Peppler
    Membre de TeamSybase - www.teamsybase.com

    "A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 12
    Points : 5
    Points
    5
    Par défaut
    Merci, mais ça ne change rien...

    Une autre idée ?

  4. #4
    Membre confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 247
    Points : 473
    Points
    473
    Billets dans le blog
    1
    Par défaut
    Peux tu nous synthétiser ta proc avec des noms parlant comme Table_A ... sans le vocabulaire métier de ton traitement ?

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 12
    Points : 5
    Points
    5
    Par défaut
    ok :

    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
     
    CREATE PROCEDURE proc AS 
    BEGIN
    	DECLARE @res varchar(255)
    	,	@resultat varchar(255)
    	,	@id varchar(50)
     
    	-- Table1   ==> OK pour cette table
    	DECLARE curs CURSOR FOR SELECT id, nom FROM table1
     
    	OPEN curs
    	FETCH curs INTO @id, @res
     
    	WHILE @@SQLSTATUS = 0
    	BEGIN
    		EXEC gen_champ @res, @resultat OUTPUT	
    		UPDATE table1 SET champ = @resultat WHERE id = @id
    		FETCH curs INTO @id, @res
    	END
     
    	CLOSE curs
    	DEALLOCATE CURSOR curs
     
            -- ... d'autres tables... 
     
    	-- Table5 ==> NON OK
    	DECLARE curs CURSOR FOR SELECT id, nom FROM table5
     
    	OPEN curs
    	FETCH curs INTO @id, @res
     
    	WHILE @@SQLSTATUS = 0
    	BEGIN
    		EXEC gen_champ @res, @resultat OUTPUT
    		UPDATE table5 SET champ = @resultat WHERE id = @id
    		FETCH curs INTO @id, @res
    	END
     
    	CLOSE curs
    	DEALLOCATE CURSOR curs
     
    	-- Table6 ==> OK pour cette table
    	DECLARE curs CURSOR FOR SELECT id, nom FROM table6
     
    	OPEN curs
    	FETCH curs INTO @id, @res
     
    	WHILE @@SQLSTATUS = 0
    	BEGIN
    		EXEC gen_champ @res, @resultat OUTPUT		
    		UPDATE table6 SET champ = @resultat WHERE id = @id
    		FETCH curs INTO @id, @res
    	END
     
    	CLOSE curs
    	DEALLOCATE CURSOR curs
     
    	-- Table7 ==> NON OK
    	DECLARE curs CURSOR FOR SELECT nom FROM table7
     
    	OPEN curs
    	FETCH curs INTO @res
     
    	WHILE @@SQLSTATUS = 0
    	BEGIN
    		EXEC gen_champ @res, @resultat OUTPUT
    		UPDATE table7 SET champ = @resultat WHERE nom = @res
    		FETCH curs INTO @res
    	END
     
    	CLOSE curs
    	DEALLOCATE CURSOR curs
     
    	-- Table8 ==> OK pour cette table
    	DECLARE curs CURSOR FOR SELECT id, nom FROM table8
     
    	OPEN curs
    	FETCH curs INTO @id, @res
     
    	WHILE @@SQLSTATUS = 0
    	BEGIN
    		EXEC gen_champ @res, @resultat OUTPUT
    		UPDATE table8 SET champ = @resultat WHERE id = @id
    		FETCH curs INTO @id, @res
    	END
     
    	CLOSE curs
    	DEALLOCATE CURSOR curs
     
    	-- ... d'autres tables... 
     
    	RETURN 0
    END
    Même si je sors de ma proc les tables concernées (en créant d'autres procédures), j'ai le même problème pour ces tables...

    Merci

  6. #6
    Membre chevronné

    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 307
    Détails du profil
    Informations personnelles :
    Âge : 64
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 307
    Points : 1 828
    Points
    1 828
    Par défaut
    Vérifie le code de la proc "gen_champs" - est-ce qu'elle a un "set rowcount" quelque part ?

    Michael
    Michael Peppler
    Membre de TeamSybase - www.teamsybase.com

    "A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 12
    Points : 5
    Points
    5
    Par défaut
    Ca ne change rien non plus...

    Cette procédure sert juste à remplacer des caractères accentués par des caractères non accentués.

    La voici (en partie) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    CREATE PROCEDURE gen_champ (@donnee VARCHAR(255), @sortie VARCHAR(255) OUTPUT) AS 
    BEGIN	
    	SELECT @donnee = STR_REPLACE(@donnee, '-', '-')
    	SELECT @donnee = STR_REPLACE(@donnee, ' ', '-')
    	-- ...
     
    	SELECT @sortie = LOWER(@donnee)
    END
    Ce qui m'intrigue le plus, c'est que pour la plupart des tables, tout se passe bien : donc il me semble que le problème ne vient pas des procédures.
    Si je lance plusieurs fois le chargement sur les tables traitées en partie, elles finnisent par être completement traitées (et de plus, je n'ai pas d'erreur renvoyée) : donc le problème ne vient pas des tables non plus.
    Si j'isole le traitement de ces tables dans une autre procédure, j'ai le même problème : donc pas un problème de mémoire (d'autant plus que ces tables contiennet moins de 1000 lignes).

    Donc, d'où vient le problème ???

    Merci pour votre aide.

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 12
    Points : 5
    Points
    5
    Par défaut
    Si je rajoute un PRINT de @@ROWCOUNT après les FETCH :

    exécution1 :
    rowcount : 1
    rowcount : 2
    rowcount : 3
    rowcount : 3
    (1 row affected)
    (return status = 0)

    exécution2 :
    rowcount : 1
    rowcount : 2
    rowcount : 3
    rowcount : 4
    rowcount : 5
    rowcount : 5
    (1 row affected)
    (return status = 0)

    exécution3 :
    rowcount : 1
    rowcount : 2
    rowcount : 3
    rowcount : 4
    rowcount : 5
    rowcount : 6
    rowcount : 6
    (1 row affected)
    (return status = 0)

    et ainsi de suite...

  9. #9
    Membre chevronné

    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 307
    Détails du profil
    Informations personnelles :
    Âge : 64
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 307
    Points : 1 828
    Points
    1 828
    Par défaut
    Je ne vois pas vraiment où pourrait être le problème - la boucle du fetch par curseur semble correcte.
    Un dbcc checktable() de l'une ou l'autre table source serait peut-être judicieux juste pour s'assurer qu'il n'y a pas de corruption.

    Michael
    Michael Peppler
    Membre de TeamSybase - www.teamsybase.com

    "A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson

  10. #10
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 12
    Points : 5
    Points
    5
    Par défaut
    le DBCC CHECKTABLE ne donne rien, les tables ne sont pas endomagées...

    Merci quand même pour ton aide.

  11. #11
    Membre confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 247
    Points : 473
    Points
    473
    Billets dans le blog
    1
    Par défaut
    Tu updates une table sur laquelle tu as ouvert un curseur FOR SELECT.

    La syntaxe FOR UPDATE couplé avec update table set champ=??? where current of ton_curseur serait peut etre plus adaptée.

    Merci de nous tenir au courant.

    Le champs mis à jour ne serait il pas dans la clé ou un index ?
    Quel est le shema de verrouillage des tables qui posent probleme ?

  12. #12
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 12
    Points : 5
    Points
    5
    Par défaut
    Je viens de trouver quelque chose : les tables concernées n'ont pas de clé primaire.

    En changeant mon curseur en UPDATE et en faisant l'update avec 'where CURRENT OF curs", j'ai l'erreur suivante :

    The optimizer could not find a unique index which it could use to scan table 'motcle' for cursor 'curs'.
    (return status = -6)


    Celà dit, dans la version inotiale du script, je n'utilisait pas de clé puisque je faisait un update sur "id = @id" ou "nom = @res" (id et nom n'étant pas définis comme clé primaires)

    Donc ma question : comment faire un update sur des tables sans clé ?

    Merci

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    79
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 79
    Points : 78
    Points
    78
    Par défaut
    Citation Envoyé par ysae17
    Je viens de trouver quelque chose : les tables concernées n'ont pas de clé primaire.

    En changeant mon curseur en UPDATE et en faisant l'update avec 'where CURRENT OF curs", j'ai l'erreur suivante :

    The optimizer could not find a unique index which it could use to scan table 'motcle' for cursor 'curs'.
    (return status = -6)


    Celà dit, dans la version inotiale du script, je n'utilisait pas de clé puisque je faisait un update sur "id = @id" ou "nom = @res" (id et nom n'étant pas définis comme clé primaires)

    Donc ma question : comment faire un update sur des tables sans clé ?

    Merci
    Pour faire un update via un curseur sur une table sans clés, il faut que le schéma de la table soit en datarows (ce qui identifie de façon unique tes lignes, en résumé tu as un id implicite).

    Par contre changer le schéma de ta table n'est peut être pas conseillé, je m'explique cela va solutionner ton problème lié à ton curseur mais risque de te créer d'autres problèmes (accès aux data, etc ...).

    Quel est le problème, pourquoi tu ne peux pas mettre une clé ?

  14. #14
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 12
    Points : 5
    Points
    5
    Par défaut
    Effectivement, je peux modifier mes tables pour rajouter une clé, mais cette solution est difficilement envisageable car elles sont utilisées par beaucoup d'applications.

    Existe-t-il une autre solution ?

    (et est-ce que quelqu'un pourrait m'expliquer ce phénomène? Pourquoi lors d'un update d'une table sans clé, seules quelques lignes sont prises en compte, puis un peu plus, et ainsi de suite...?)

    Merci

  15. #15
    Membre chevronné

    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 307
    Détails du profil
    Informations personnelles :
    Âge : 64
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 307
    Points : 1 828
    Points
    1 828
    Par défaut
    Le problème c'est que le curseur crée un plan d'exécution, et qu'en updatant la table "sous lui" tu fais en sorte que la suite des lignes à lire devient incorrecte et ASE pense qu'il n'y a plus de lignes à lire.

    Michael
    Michael Peppler
    Membre de TeamSybase - www.teamsybase.com

    "A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson

  16. #16
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 12
    Points : 5
    Points
    5
    Par défaut
    Ok, je crois que j'ai compris.

    Donc normalement, en passant par une table temporaire (avec une clé celle-là) ça devrait être bon.
    Je vous tiens au courant.

    Merci pour votre aide.

  17. #17
    Membre confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 247
    Points : 473
    Points
    473
    Billets dans le blog
    1
    Par défaut
    A mon avis cela devrait marcher :
    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
    	select id,nom into #T_curseur
    DECLARE curs CURSOR FOR SELECT id, nom FROM #T_curseur
     
    	OPEN curs
    	FETCH curs INTO @id, @res
     
    	WHILE @@SQLSTATUS = 0
    	BEGIN
    		EXEC gen_champ @res, @resultat OUTPUT
    		UPDATE table5 SET champ = @resultat WHERE id = @id
    		FETCH curs INTO @id, @res
    	END
     
    	CLOSE curs
    	DEALLOCATE CURSOR curs
    Et la, le curseur étant décorrelé de la table updatée , je pense que tu ne devrais plus avoir de probleme.

  18. #18
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    79
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 79
    Points : 78
    Points
    78
    Par défaut
    Citation Envoyé par ysae17
    Bonjour,

    Voici mon problème :
    j'ai une procédure stockée qui permet des mettre à jour un champ dans plusieurs tables.
    Mon problème est que pour certaines tables ça marche sans problème et pour d'autres seules quelques lignes sont traitées et aucune erreur n'est retournée.
    Si je relance la procédure pour ces tables, quelques lignes sont traitées en plus (par exemple, au premier passage, 2 lignes sont traitées, puis 5, puis 10... c'est complètement aléatoire), de sorte que si je lance la procédure assez de fois, toute la table est traitée.

    Est-ce que quelqu'un a déjà eu ce type de problème ? et si oui, d'où cela peut-il venir ?

    Merci
    Pour utiliser un curseur sur une table celle ci doit :
    - soit avoir un clé
    - soit un schéma datarow

    Si vous ne respectez pas ces conditions vous obtenez des comportements aléatoire car le curseur n'a pas de moyens pour identifier les enregistrements de façon unique.

  19. #19
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 12
    Points : 5
    Points
    5
    Par défaut
    Ca marche !

    Merci à tous pour votre aide.

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

Discussions similaires

  1. Petit problème avec une procédure stockée
    Par Poulain dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 18/05/2007, 19h58
  2. [VB.NET 2.0] - Problème avec une procédure stockée
    Par Khrysby dans le forum Accès aux données
    Réponses: 1
    Dernier message: 14/05/2007, 16h25
  3. Réponses: 2
    Dernier message: 06/12/2006, 09h54
  4. Problème avec une procédure stockée
    Par in dans le forum Langage SQL
    Réponses: 4
    Dernier message: 27/05/2003, 16h33

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