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 :

Aide pour ré-indexation alphabétique


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mars 2009
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 29
    Points : 11
    Points
    11
    Par défaut Aide pour ré-indexation alphabétique
    Bonjour,

    Casse tête pour un débutant comme moi.

    Une table partenaires (OCRD) dont les fournisseurs sont indexés dans un champ (CardCode) sur le modèle Fxxxxx. On souhaite pouvoir réutiliser les trous de l'index (suite aux suppressions dans la table) pour réinsérer les nouveaux fournisseurs dans l'ordre alphabétique du champ nom (CardName).

    Problème : l'historique est très anarchique et je ne peux pas utiliser le classement sur CardName pour positionner le CardCode.

    Pou y parvenir, j'aimerai créer une sous requête qui me renvoie OCRD purgée de tous les enregistrements ne respectant pas l’ordre alphabétique.

    Ce qui donne un code du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT T0.[CardCode], T0.[CardName]
    FROM OCRD T0
    WHERE (LEFT ( T0.[CardCode] , 1) = 'F')
          AND T0.CardName < (SELECT CardName FROM OCRD WHERE CardCode > @CardCode )
    ORDER BY T0.[CardCode]
    ou @CardCode représente le CardCode de l'enregistrement traité par le SELECT de niveau supérieur qui doit être utilisé par le SELECT du niveau le plus imbriqué pour comparaison (et éventuellement rejet) de son CardName avec tous les enregistrements qui suivent.

    Désolé si je suis peu clair mais si ça l'était je n'aurai pas besoin d'aide ;-)

    Je sais que mon code n'est pas conforme mais existe-t-il une solution pour ce type de comparaison des enregistrements d'une même table ?

    Merci de votre aide.

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 394
    Points
    18 394
    Par défaut
    Citation Envoyé par oliviers92 Voir le message
    Une table partenaires (OCRD) dont les fournisseurs sont indexés dans un champ (CardCode) sur le modèle Fxxxxx. On souhaite pouvoir réutiliser les trous de l'index (suite aux suppressions dans la table) pour réinsérer les nouveaux fournisseurs dans l'ordre alphabétique du champ nom (CardName).
    Houla, que d'énormités.
    En base de données, grosso modo, on ne bouche pas les trous libres, un identifiant cramé reste cramé.
    On ne trie pas ses données dans la table, on le fait à l'exécution avec une requête.

    Imaginez que vous faites votre mise à jour et, puis un nouveau fournisseur "ABC" se présente. Comptez-vous redécaler tous vos codes ?

  3. #3
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mars 2009
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 29
    Points : 11
    Points
    11
    Par défaut
    Bonjour,

    Je n'ai pas dit que c'était une bonne idée. Simplement une demande utilisateur. Rien n'oblige a satisfaire les demandes farfelues me direz-vous, mais il se trouve que celle-ci n'est pas totalement injustifiée. Il n'est donc pas totalement interdit de chercher à la satisfaire dans la mesure du possible. L'objectif est bien celui-ci : réutiliser les trous disponibles pour obtenir un index le plus proche possible de l'ordre alphabétique.

    Malgré mon inexpérience j'ai imaginé et argumenté vis à vis des utilisateurs l'écueil que vous pointez. Reste le besoin. Je n'ai malheureusement pas la possibilité d'intervenir au niveau d'une requête comme vous le suggérez. Il s'agit d'un état standard de l'ERP qui est trié par l'index là ou les utilisateurs le souhaiteraient trié par ordre alphabétique pour des raisons de confort de lecture évidentes. Je n'ai manifestement pas la possibilité de recréer le "grand livre" de SAP Business One par moi-même !

    Même si la critique et la mise en garde a tout son intérêt didactique, il m'aurait été plus utile de profiter de votre savoir pour résoudre mon problème.

  4. #4
    Membre chevronné
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Points : 1 806
    Points
    1 806
    Par défaut
    Citation Envoyé par oliviers92 Voir le message
    Une table partenaires (OCRD) dont les fournisseurs sont indexés dans un champ (CardCode) sur le modèle Fxxxxx. On souhaite pouvoir réutiliser les trous de l'index (suite aux suppressions dans la table) pour réinsérer les nouveaux fournisseurs dans l'ordre alphabétique du champ nom (CardName).

    Problème : l'historique est très anarchique et je ne peux pas utiliser le classement sur CardName pour positionner le CardCode.
    Je ne comprend pas le besoin. CardCode est censé représenter quoi ? Un ordre alphabétique ? Un ordre d'insertion ? Si c'est bien un ordre d'insertion, pourquoi vouloir utiliser les "trous" ? Sinon, quel est le critère qui préside à la réattribution d'une telle valeur ?
    Outre le fait que c'est une mauvaise idée (cf post de Waldar) le besoin n'est pas clair, au moins pour moi. Un exemple de ce qu'il y a en base actuellement et de ce qui est désiré semble le minimum pour bien se faire comprendre dans le cas présent.

    Si le besoin est uniquement lié à un ordre alphabétique, alors pour déterminer le nouveau rang il suffit de faire un select avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     row_number() over (order by CardName)

  5. #5
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mars 2009
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 29
    Points : 11
    Points
    11
    Par défaut
    Pour fixer les idées :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT TOP (20) T0.[CardCode], T0.[CardName] FROM OCRD T0 WHERE LEFT([CardCode],1) = 'F' ORDER BY T0.[CardCode]
    Renvoie :

    1 F00001 AJInternational
    2 F00002 CALBERSON YVELINES
    3 F00003 CCIJF
    4 F00004 ABOTT ARTISAN
    5 F00005 STANLEY SOLUTIONS DE SECURITE
    6 F00006 AGILENT TECHNOLOGIES FRANCE
    7 F00007 AIGOTEC GmbH
    8 F00008 ALD AUTOMOTIVE
    9 F00009 ALPHA MOS
    10 F00011 BSI
    11 F00012 AMT Emballages
    12 F00013 ANA SALES FRANCE SA
    13 F00014 APS Int
    14 F00015 CHATEAU D'EAU
    15 F00016 ARC EN CIEL
    16 F00017 ARVAL
    17 F00018 ASC Privée
    18 F00021 Autradet
    19 F00022 AVIS LOCATION DE VOITURES
    20 F00023 AXANTIS

    L'ensemble des partenaires sont dans la table OCRD. L'index est donc alpha numérique avec la lettre F pour discriminer les Fournisseurs des autres Partenaires.

    On voit que le CardName suit dans la mesures des aberrations historiques et des éventuelles impossibilités évoquées par Waldar l'ordre alphabétique de l'index.

    Cet index est généré automatiquement par une "Recherche formatée" s"appuyant sur une requête SQL dont je simplifie le code ici pour n'en donner que la partie correspondante à la génération de l'index dans le cas des fournisseurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    set @max = (select max(substring(cardcode, 2, 5)) from ocrd where cardcode like 'F0%%')
    set @temp = cast(@max as integer)
    set @temp = @temp + 1
    set @res = 'F' + right('00000'+cast(@temp as varchar(5)), 5)
    soit le dernier enregistrement + 1. Pour réutiliser les trous, l'objectif est de modifier la définition de la variable @max par une requête qui renvoie le premier CardCode disponible dont le CardName est inférieur à celui de l'enregistrement en cours de création.

    Problème : un trou est défini par l’enregistrement qui le précède. Comme ces enregistrements ne sont déjà pas dans l'ordre alphabétique (voir extrait de la table) cette information n'est pas fiable. Je souhaite donc me baser non pas sur OCRD brute mais sur une requête sur OCRD qui n'en renvoie que les enregistrements qui respectent l'ordre alphabétique.

    Compliqué sans aucun doute, mais je suis ouvert à toute solution dans cette voie ou dans une voie alternative.

    Merci d'avance pour vos suggestions et commentaires

  6. #6
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 920
    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 920
    Points : 51 712
    Points
    51 712
    Billets dans le blog
    6
    Par défaut
    C'est une usine à gaz dû à un modèle pourri ne respectant pas les formes normales, ni ce qu'est une table relationnelle...
    Ainsi :
    1) avoir deux informations dans une même colonne viole la 1ere forme normal (carcode composé d'une lettre et un n°)
    2) les bases de données relationnelles reposent sur la théorie des ensembles pour lesquelles la notion d'ordre (et donc elle des lignes dans une table) n'existe pas.

    Comme vous modélisez mal et partez d'un postulat faux vous obtenez une usine à gaz !

    En sus votre méthode d'auto incrémentation en faisant max + 1 est non seulement catastrophique pour les performances (nécessité d'utiliser un verrou exclusif sur toute la table) mais ne garantit en aucune manière l'unicité !
    À me lire : http://sqlpro.developpez.com/cours/clefs/

    Renvoyez de A à Z votre conception.

    A +

  7. #7
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mars 2009
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 29
    Points : 11
    Points
    11
    Par défaut
    Bonjour,

    Nous créons, tous partenaires confondus, environ 6 Partenaires par mois. Mon pragmatisme me conseil de considérer l'aspect catastrophique sur les performances comme très mineur. Serais-je pardonné ?
    Je vais de ce pas consulter attentivement l'article conseillé sur les clefs, sujet un peu plus inquiétant quant-au risque de conflit suggéré. Je ferai par ailleurs un test sur jeu d'essai pour le confirmer mais je pense que ce problème est géré au niveau du moteur de SBO.

    Je suis bien conscient de mes lacunes, je suis justement actuellement en train de lire avec application votre cours en ligne riche d'enseignements.

    Seulement il faut toujours distinguer la théorie et la pratique. Il n'est pas question de revoir la conception d'un ERP qui est en production depuis plusieurs années. Votre remarque sur la duplicité d'information au sein de CardCode tombe sous le sens d'un analyste mais a malheureusement échappé au Consultant, avant tout un comptable, qui a mis en place SAP Business One dans notre Entreprise.

    je ne suis qu'un administrateur réseau d'une PME touche-à-tout qui doit faire face à l'ensemble des problématiques en "tique" qui se présentent de l'achat à l'entretien du parc matériel et logiciel en passant par les smartphones, de la protection Antivirus et autres sujets liés à la sécurité jusqu'à la gestion du projet ERP. J'essaie donc dans la mesure de mes compétences d'apporter des réponses pratiques à des problèmes pratiques.

    Mon problème concret est donc le suivant :
    - SAP regroupe l'ensemble des ses partenaires (Clients, Fournisseurs, Prospects) dans la table OCRD (Il les distingue par un champ CardType)
    - une règle de génération automatique du champ CardCode a été mise en place selon le principe déjà décrit : Tnnnnn ou T est le type (CardType) de partenaire et nnnnn un incrément automatique sur le principe max + 1
    - le Grand Livre (état comptable que j'aurai bien du mal à vous définir) est présenté dans l'ordre alphanumérique de CardCode. Cet état comporte de nombreuses pages et les comptables souhaiteraient vivement pouvoir le consulter dans l'ordre alphabétique de CardName.
    - Historiquement CardCode et CardName avaient été créés en "correspondance" mais la lisibilité du Grand Livre se dégrade au fur et à mesure de la création des nouveaux partenaires.
    - D'ou l'idée d'utiliser les trous de CardCode ce que les comptables ont déjà commencé à faire à la main en contournant son automatisme de génération, ce qui me semble la pire des solutions.

    Maintenant que l'aspect pratique est clairement posé, je salue toutes les mises en garde et critiques qui me sont faites sur le manque d'académisme de la solution. Elles sont formatrices pour moi et surtout d'autres néophytes qui viendraient à consulter cette discussion. Reste que j'en suis toujours au même point. Il ne s'agit plus là de conception mais d'une adaptation pratique pour laquelle je ne vois guère d'autre solution que celle basée sur l'utilisation des trous si décriée. Puis-je espérer un peu d'aide ?

    PS : Si tout comme moi d'autres lecteurs de cette discussion entendent parler d'une "forme normale" pour la première fois sachez qu'il ne s'agit pas d'une simple expression mais d'un concept bien défini dans le contexte des BDR. Si j'en crois le rédacteur de l'article de Wikipedia dans le cadre de l'exemple qui nous intéresse l'utilisation du modèle Tnnnnn n'est peut-être pas si mauvais sachant que l'on travaille quasi exclusivement en lecture sur cette table et surtout sur ce champ. L’utilisateur en retire une grande facilité d'usage particulièrement lorsque l'on considère qu'une même Entreprise à la fois cliente et fournisseur donne lieu à deux Partenaires distincts. Vaut-il mieux éviter les erreurs de saisie ou respecter l'orthodoxie des normes de programmation ?

  8. #8
    Membre chevronné
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Points : 1 806
    Points
    1 806
    Par défaut
    Ce qu'il y a c'est que le besoin que vous semblez vouloir exprimer ne correspond pas du tout à ce que vous demandez.

    Vous dites vouloir utiliser "les trous" : dans l'exemple que vous donnez, il n'y en a qu'un : 19. Et je ne vois pas en quoi mettre une quelconque valeur à "cet endroit" (au sens tri sur cette valeur) changerait le fait que les comptables n'ont pas du tout de tri par ordre alphabétique. Complétez votre exemple : à quoi devrait ressembler la table d'arrivée ???

    À mon avis, le besoin c'est une réindexation complète, sans aucun rapport avec les éventuels trous, non ? Et pour ça il n'y a qu'un update massif avec un tri sur CardName qui pourra le faire. En espérant que CardCode n'est pas la clé primaire (référencée par des clés étrangères) de votre table ... Donnez-nous la définition de la table et le SGBDR que vous utilisez.

  9. #9
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mars 2009
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 29
    Points : 11
    Points
    11
    Par défaut
    Bonjour,

    L'application est SAP Business One implanté sur un serveur MS-SQL 2005.
    Pardonnez mon ignorance mais qu’appelez vous la définition de la table ? OCRD comporte une bonne centaine de champs, je ne vois guère en pratique comment la définir de manière précise et exhaustive.

    je n'ai donné que les 20 premières lignes à titre d'exemple pour faciliter la compréhension de la structure, je ne vois guère l'intérêt de vous donner 300 lignes de partenaires pour vous prouver qu'il existe bien des trous dans l'index CardCode.

    Il me semble que l'incompréhension vient aussi que vous experts raisonnez en développeurs et administrateurs de bases que vous maîtrisez de A à Z. Indépendamment de mes connaissances ça n'est pas mon cas. les contraintes à intégrer sont :

    - SAP n'autorise pas les manipulations directes sur la base. l'UPDATE est totalement exclu.
    - Indépendamment de la politique de SAP il n'est pas envisageable de ré indexer les Partenaires pour lesquels il existe des liens vers des documents d'achat par exemple.
    - le "Grand Livre" est un état comptable généré par l'application sans option d'ordonnancement. Aussi bien à l'écran que la sortie papier il est et restera indexé selon CardCode sauf à payer X journées de Consultant pour le développement d'un état spécifique.

    Partant de là aussi bien les comptables demandeuses que moi même sommes conscients que la solution des trous est un pis-aller, qu'il ne résoudra rien pour l'existant "désindexé" et dans le cas de créations ou l'absence de trous ne permettra pas la réinsertion dans l'ordre alphabétique. Mais en pratique, limiter la désorganisation au maximum limitera également les cas ou elles devront rechercher un partenaire parmi un état qui sauf erreur de ma part représente plus d'une centaine de pages.

    le besoin que j'exprime est donc le suivant :
    J'ai déjà mis au point une requête qui me permet de déterminer les trous sur le principe (je simplifie le code) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT MIN(CardCode) FROM OCRD WHERE CardCode NOT IN (SELECT CardCode FROM OCRD)
    Il me manque une requête me donnant une OCRD épurée des "CardName" hors de l'ordre alphabétique, appelons la OCRDA, qui me permettrait d'ajouter une condition dans le WHERE du type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AND CardName > (SELECT MIN(CardName) FROM OCRDA WHERE CardName > @FormCardName)
    Je simplifie également mais @FromCardName représente une variable renvoyée par SAP donnant la valeur du CardName en cours de création.

    Sauf erreur de ma part j'aurai bien ainsi l’attribution du premier trou disponible pour lequel le CardName sera le plus proche possible de l’ordre alphabétique (jamais avant mais peut-être après en l'absence de trou disponible au "bon endroit"). je met des guillemets à "bon endroit" pour que les puristes comprennent que j'ai bien assimilé le concept "ensembliste" des SGBDR ;-)

    La question est comment créer OCRDA.

    Merci d'avance pour votre aide et votre temps

  10. #10
    Expert éminent sénior
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 801
    Points : 34 063
    Points
    34 063
    Billets dans le blog
    14
    Par défaut
    Moi aussi, j'ai du mal à comprendre le besoin !
    - le Grand Livre (état comptable que j'aurai bien du mal à vous définir) est présenté dans l'ordre alphanumérique de CardCode. Cet état comporte de nombreuses pages et les comptables souhaiteraient vivement pouvoir le consulter dans l'ordre alphabétique de CardName.
    Quel rapport avec le bouchage des trous dans CardCode ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT -- les colonnes souhaitées
    FROM -- la table
    WHERE -- éventuellement une condition de restriction parce que le grand livre est gros
    ORDER BY CardName

  11. #11
    Membre chevronné
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Points : 1 806
    Points
    1 806
    Par défaut
    Citation Envoyé par oliviers92 Voir le message
    Bonjour,

    L'application est SAP Business One implanté sur un serveur MS-SQL 2005.
    Pardonnez mon ignorance mais qu’appelez vous la définition de la table ? OCRD comporte une bonne centaine de champs, je ne vois guère en pratique comment la définir de manière précise et exhaustive.
    Le script de création de la table, tout simplement. Cela dit, en l'occcurence ce qui est intéressant c'est surtout la clé primaire et/ou les clés étrangères.

    je n'ai donné que les 20 premières lignes à titre d'exemple pour faciliter la compréhension de la structure, je ne vois guère l'intérêt de vous donner 300 lignes de partenaires pour vous prouver qu'il existe bien des trous dans l'index CardCode.
    L'intérêt c'est surtout à partir de valeurs, de savoir ce que vous attendez comme résultat. Donner de quoi générer 2 ou 3 cas de tests, ça permet de comprendre le besoin. Cela dit, je viens de comprendre en relisant posément votre premier post en combinaison avec le dernier, que vous ne souhaitez pas du tout réindexer, mais juste déterminer le 1er emplacement "disponible" qui colle à ce que vous estimez être un ordre alphabétique.

    Par contre :
    Il me manque une requête me donnant une OCRD épurée des "CardName" hors de l'ordre alphabétique, appelons la OCRDA, qui me permettrait d'ajouter une condition dans le WHERE du type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AND CardName > (SELECT MIN(CardName) FROM OCRDA WHERE CardName > @FormCardName)
    Là il faudrait déterminer ce qui détermine le bon ordre alphabétique. De façon récursive en partant du 1er élément (et en espérant qu'il est plutôt vers le début de l'alphabet ...) ?

    En reprenant votre exemple, le 1er trou est en fait à 10. Si on regarde les éléments :
    1 F00001 AJInternational
    2 F00002 CALBERSON YVELINES
    3 F00003 CCIJF
    4 F00004 ABOTT ARTISAN
    5 F00005 STANLEY SOLUTIONS DE SECURITE
    6 F00006 AGILENT TECHNOLOGIES FRANCE
    7 F00007 AIGOTEC GmbH
    8 F00008 ALD AUTOMOTIVE
    9 F00009 ALPHA MOS
    10 F00011 BSI
    Si je procède de façon récursive ... On commence à AJInternational :
    CALBERSON YVELINES - OK ordre alphabétique
    CCIJF - OK ordre alphabétique
    ABOTT ARTISAN - KO
    STANLEY SOLUTIONS DE SECURITE - OK !
    Et tout d'un coup on a déjà sauté au S, ce qui fait que tout le reste sera ko ... moralité, on va estimer que la 1ère place disponible devrait prendre une valeur > STANLEY. Quelque chose me dit que ça va rapidement poser problème ! Posez-vous la question : à quel index devrait arriver telle valeur ? Selon quel algorithme ? Personnellement je doute que vous puissiez avoir quelque chose de ne serait-ce que vaguement correct vu les valeurs que vous présentez : l'ordre de base est trop cassé. Peut-être qu'avec une grosse moyenne sur 5 valeurs avant et 5 valeurs après ... mais j'en doute sérieusement.

    Cela dit, j'ai quand même beaucoup de mal à croire que SAP ne permette pas de paramétrer l'ordre de sortie d'un état.

  12. #12
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mars 2009
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 29
    Points : 11
    Points
    11
    Par défaut
    Pour répondre à CinePhil l'idée est de préserver une correspondance de classement des deux champs. CardCode qui est celui utilisé par l'application dans son tri, CardName qui est celui des noms intelligibles pour les utilisateurs.
    Merci pour le modèle de requête avec ORDER BY sur CardName, je crois que je ne me serais pas lancé sur ce forum si je n'étais pas capable d'écrire cela, mais surtout pour mémoire je n'ai pas la possibilité d'entrer dans le code de SAP pour reconstruire ses fonctions ! je ne peux intervenir qu'au niveau de la "recherche formatée" qui sert à générer le CardCode.

    J'avoue avoir jusque là considéré la demande des utilisatrices comme une preuve de l'absence de possibilité de classement du "Grand Livre". Après contrôle je suis au regret de devoir leur donner raison. on voit sur l'image Gd Livre.jpg en PJ qu'il est borné et donc indexé sur Code (ou CardCode). Après une lueur d'espoir en découvrant l'option "Trier et regrouper" c'est la désillusion en découvrant que le seul champ correspondant un peu à la demande est CardCode et nom CardName (voir Tri.jpg). Notez qu'il s'agit de SAP Buisness One c-à-d le produit d'entrée de gamme de SAP destiné aux PME.

    Pas sûr que le script soit très utile mais je le joint également cela m'a permis de découvrir cette fonction dans SQL Server Management Studio.

    Merci à Rei Ichido, nous entrons enfin dans le vif du sujet et vous avez justement pointé la seule difficulté du problème. Je veux utiliser le premier trou (F00010) si et seulement si
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    @FromCardName > (SELECT CardName FROM OCRD WHERE CardCode < F00010)
    Seulement pour que cela fonctionne il faut éliminer les CardName qui ne respectent pas l'ordre alphabétique tel que F00005 (STANLEY SOLUTIONS DE SECURITE).

    Pour ce qui est de l’algorithme j'étais plutôt parti dans mon message initial sur l'idée que le CardName doit être < à tous les CardName correspondants aux CardCode qui le suivent

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT T0.[CardCode], T0.[CardName]
    FROM OCRD T0
    WHERE (LEFT ( T0.[CardCode] , 1) = 'F')
          AND T0.CardName < (SELECT CardName FROM OCRD WHERE CardCode > @CardCode )
    ORDER BY T0.[CardCode]
    Soit :

    1 F00001 AJInternational
    2 F00002 CALBERSON YVELINES
    3 F00003 CCIJF
    4 F00004 ABOTT ARTISAN
    5 F00005 STANLEY SOLUTIONS DE SECURITE
    6 F00006 AGILENT TECHNOLOGIES FRANCE
    7 F00007 AIGOTEC GmbH
    8 F00008 ALD AUTOMOTIVE
    9 F00009 ALPHA MOS
    10 F00011 BSI
    11 F00012 AMT Emballages
    12 F00013 ANA SALES FRANCE SA
    13 F00014 APS Int
    14 F00015 CHATEAU D'EAU
    15 F00016 ARC EN CIEL
    16 F00017 ARVAL
    17 F00018 ASC Privée
    18 F00021 Autradet
    19 F00022 AVIS LOCATION DE VOITURES
    20 F00023 AXANTIS

    Il faudrait voir en pratique ce que cela donne sur l'ensemble de la base mais sans le code qui me manque depuis le début ...
    Images attachées Images attachées   
    Fichiers attachés Fichiers attachés

  13. #13
    Expert éminent sénior
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 801
    Points : 34 063
    Points
    34 063
    Billets dans le blog
    14
    Par défaut
    Pour répondre à CinePhil l'idée est de préserver une correspondance de classement des deux champs. CardCode qui est celui utilisé par l'application dans son tri, CardName qui est celui des noms intelligibles pour les utilisateurs.
    Désolé mais j'ai toujours du mal à comprendre !

    Vous voulez modifier les CardCode en fonction du classement des CardName ?

    Ça me semble très casse-gueule comme démarche !

    Soit ce CardCode est une clé utilisée en référence dans d'autres tables et vous allez foutre la pagaille dans l'intégrité de la BDD !
    Prévenez votre patron qu'il prépare son carnet de chèques pour se payer un consultant SAP pour réparer les dégâts !

    Soit ce CardCode a une signification, par exemple si c'est le numéro de partenaire figurant sur les factures et les commandes.
    Et si vous modifiez cela, un jour ou l'autre, un fournisseur téléphonera en disant je suis le fournisseur F12345 et ma facture du mois de janvier ne m'a pas encore été payée... sauf que maintenant, pour vous, ce n'est plus le F12345 mais le F54821 d'où, là aussi, pagaille !

    On ne touche pas à ce genre d'identifiants sans bien mesurer les risques et les conséquences !
    Un identifiant, qu'il soit purement numérique ou alphanumérique, n'est qu'un identifiant, en principe sans signification et ne garantit aucun ordre par lui même.

    En tout cas, cette discussion me confirme dans l'idée que je m'étais faite, à la lecture d'autres discussion, que SAP a un modèle pourri et obscur et ne donne pas du tout envie de travailler avec un jour !

  14. #14
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mars 2009
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 29
    Points : 11
    Points
    11
    Par défaut
    Relisez posément depuis le début et tout devrait être clair.

    Il n'est question que d'utilisez les CardCode (clef Primaire de la table) disponibles parce qu'effacés et donc inutilisés au cours de la vie de la base (SBO ne permet évidemment pas la suppression des Partenaires liés à d'autres tables) pour que les CardName des nouveaux Partenaires apparaissent dans un ordre confortable dans le "Grand Livre". On ne modifie donc rien de l'historique mais on créé selon une règle correspondant à notre souhait.

    Pour les modèles de SAP en général et SBO en particulier je n'ai pas la prétention de pouvoir en juger mais je crois surtout que la conception de bases et le paramétrage d'une application commerciale telle que SBO ne sont pas du tout le même métier. Dans un cas on fait ce que l'on veut en fonction d'un cahier des charges bien précis que l'on maîtrise de A à Z, dans l'autre on ne dispose que de "Recherches Formatées" et de "Transaction Notifications" pour adapter un produit rigide (car tronc commun à l'ensemble des clients) aux besoins spécifiques d'un client.

    Encore une fois, j'ai bien compris la vision ensembliste des SGBDR mais dans ce cas concret il se trouve que SAP a programmé son "Grand Livre" dans l'ordre alphanumérique de CardCode et que nous le voulons dans l'ordre alphabétique de CardName. Voilà tout.

    Si vous admettez cela, il ne reste plus qu'à trouver un moyen de faire en sorte que les deux coïncident aux impossibilités historique et aux indisponibilités de trous près.

  15. #15
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Bonjour,

    Et pourquoi ne faites-vous pas simplement évoluer l'affichage de votre "grandLivre" afin de restituer vos informations avec l'ordre que vous voullez ?


    "boucher" des trous d'une clef primaire n'est pas une solution en soit.
    Vous arriverez surement à trouver un pseudo algo mais qui fera partiellement ce qu'une évolution simple fera complètement, et en moins compliqué.


    Là en bouchant, avec un cas simple comme celui-ci on voit déjà les limites d'un tel acte :

    création du fournisseur ABC => 1er trou 50eme position
    création du fournisseur AAA => 1er trou en 88eme position
    création du fournisseur .... => ...

  16. #16
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mars 2009
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 29
    Points : 11
    Points
    11
    Par défaut
    - le "Grand Livre" est un état comptable généré par l'application sans option d'ordonnancement. Aussi bien à l'écran que la sortie papier il est et restera indexé selon CardCode sauf à payer X journées de Consultant pour le développement d'un état spécifique.
    Il suffit de jeter un oeil sur l'image Gd Livre.jpg pour en déduire que l'opération est suffisamment compliquée pour que X dépasse le budget d'une PME.

    je n'ai pas la possibilité d'entrer dans le code de SAP pour reconstruire ses fonctions ! je ne peux intervenir qu'au niveau de la "recherche formatée" qui sert à générer le CardCode.
    Si vous admettez cela, il ne reste plus qu'à trouver un moyen de faire en sorte que les deux coïncident aux impossibilités historique et aux indisponibilités de trous près.
    J'ai bien saisi les limitations de la solution des trous. Reste qu'elle est mieux que rien.

  17. #17
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 950
    Points : 5 849
    Points
    5 849
    Par défaut
    A mon avis il y a un problème que vous n'avez pas envisagé, c'est qu'il est probablement également interdit de modifier la génération de la séquence cardcode faite par SAP, sous peine de ne plus être supporté...
    Donc je vous conseille de vous renseigner avant de faire ce genre de modif.

    Sinon tous les conseils de mis en garde étant déjà prodigué, je vous propose une requête qui semble fonctionner (et qu'évidemment je n'utiliserais jamais, mais je prends ça comme un challenge SQL...)
    Il faut vous assurer que la table est bien vérouillée lors de ce process de génération de clé mais je pense que SAP le faisait déjà.
    Malheureusement pour vous j'ai développé la requête sous oracle, il vous faudra donc la modifier quelque peu pour SQLServer, la logique est normalement compatible :
    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
    SQL>   with rn_ocrd as (
      2  select cardcode, cardname,
      3         row_number() over(order by cardcode desc) as rn
      4    from OCRD o
      5   where cardcode like 'F0%'
      6  ),
      7         rec_rn_ocrd (cardcode, cardname, comp_cardcode, comp_cardname, trou, rn) as (
      8  select cardcode, cardname, cardcode, cardname, 0, 1
      9    from rn_ocrd
     10   where rn = 1
     11   union all
     12  select r.cardcode, r.cardname,
     13         case when r.cardname < rec.comp_cardname
     14              then r.cardcode
     15              else rec.comp_cardcode
     16          end as comp_cardcode,
     17         case when r.cardname < rec.comp_cardname
     18              then r.cardname
     19              else rec.comp_cardname
     20          end as comp_cardname,
     21         case when cast(substr(r.cardcode, 2, 5) as int) <> cast(substr(rec.cardcode, 2, 5) as int)- 1
     22              then 1
     23              else 0
     24          end as trou,
     25         rec.rn + 1
     26    from rn_ocrd r
     27    join rec_rn_ocrd rec on r.rn = rec.rn + 1
     28  ),
     29         tri_orcd as (
     30  select distinct comp_cardcode as cardcode, comp_cardname as cardname, trou
     31    from rec_rn_ocrd
     32  ),
     33         rn_tri_orcd as (
     34  select cardcode, cardname, trou, row_number() over(order by cardcode desc) as rn
     35    from tri_orcd
     36  ),
     37         dispo_cardcode as (
     38  select cardcode, cardname
     39    from rn_tri_orcd
     40   where rn = 1
     41      or trou = 1
     42  )
     43  select 'F'||lpad(coalesce(max(cast(substr(case when cardname < 'ASC2'
     44                                                 then cardcode
     45                                             end, 2, 5) as int)) + 1,
     46                            max(cast(substr(cardcode, 2, 5) as int)) + 1), 5, '0') as res
     47    from dispo_cardcode;
     
    RES
    ---------------------
    F00019
     
    SQL>
    En bref à modifier je dirais :
    - from dual à retirer
    - substr => substring
    - lpad => reprendre la logique du right...
    - || => + je crois pour la concaténation

    Et évidemment remplacer 'ASC2' dans mon exemple par @FormCardName

    Il ne vous reste plus qu'à vous documenter sur les requêtes récursives, les fonctions analytiques et les CTE.

    [EDIT] J'ai modifié le code pour gérer le cas d'un cardname nouveau et très petit comme AA...

  18. #18
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mars 2009
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 29
    Points : 11
    Points
    11
    Par défaut
    Pour ce qui est du support en fait je me borne à modifier la RF (nommée OCRD CardCode (auto)) mise en place par l'intégrateur SAP dont le code (déjà cité partiellement) est le suivant :

    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
    declare @temp as integer
    declare @max as varchar(6)
    declare @res as char(6)
    if $[$40.0.0]='C'
    set @max = (select max(substring(cardcode, 2, 5)) from ocrd where CardCode like 'C0%%')
    if $[$40.0.0]='L'
    set @max = (select max(substring(cardcode, 2, 5)) from ocrd where cardcode like 'P0%%')
    if $[$40.0.0]='S'
    set @max = (select max(substring(cardcode, 2, 5)) from ocrd where cardcode like 'F0%%')
    set @temp = cast(@max as integer)
    set @temp = @temp + 1
    if $[$40.0.0]='C'
    set @res = 'C' + right('00000'+cast(@temp as varchar(5)), 5)
    if $[$40.0.0]='L'
    set @res = 'P' + right('00000'+cast(@temp as varchar(5)), 5)
    if $[$40.0.0]='S'
    set @res = 'F' + right('00000'+cast(@temp as varchar(5)), 5)
     
    select case @res
    when ' ' then cast(' ' + @res as varchar)
    else
    cast(@res as varchar)
    end
    Ca, c'est permis moyennant éventuellement une consultation de l'intégrateur.
    Pas de problème de verrou, j'ai déjà confirmé, suite au message alarmant de SQLPro, que l'on ne peut pas écraser un enregistrement existant.

    Je vais donc essayer de modifier la section d'affectation du CardCode correspondant au cas des fournisseurs (if $[$40.0.0]='S').

    Ou $[$40.0.0] est le CardCode de l'enregistrement en cours de saisie
    avec une condition sur $[$7.0.0] qui est son équivalent pour CardName (que j'avais défini comme @FormCardName).

    Il ne me reste plus qu'à digérer le code car la, on est passé un cran au-dessus pour moi !

    Mais d'ores et déjà un grand merci.

  19. #19
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 950
    Points : 5 849
    Points
    5 849
    Par défaut
    En fait ça ne fonctionne pas très bien... Avec lead/lag ce serait peut être plus simple mais ça ne fonctionne pas avec SqlServer 2005.

    Si j'ai une meilleure idée je la proposerais plus tard.

  20. #20
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    445
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 445
    Points : 622
    Points
    622
    Par défaut
    Bonjour,

    A moins que vous ayez énormément de trous, j'ai l'impression qu'une solution automatique risque de vous donner un résultat plus que moyen.

    Vous pouvez peut être faire en sorte que vos nouveaux fournisseurs soient insérés (presque) triés à la fin de l’état ( ou ou début, mais ça risque d'être plus compliqué).

    Admettons que vous ayez ces nouveaux fournisseurs:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    AJInternational
    CALBERSON YVELINES
    CCIJF
    ABOTT ARTISAN
    STANLEY SOLUTIONS DE SECURITE
    AGILENT TECHNOLOGIES FRANCE
    AIGOTEC GmbH
    ALPHA MOS
    ALD AUTOMOTIVE
    BSI
    Ça pourrait donner quelque chose comme ça:
    F0AB01 ABOTT ARTISAN
    F0AG01 AGILENT TECHNOLOGIES FRANCE
    F0AI01 AIGOTEC GmbH
    F0AJ01 AJInternational
    F0AL01 ALPHA MOS
    F0AL02 ALD AUTOMOTIVE
    F0BS01 BSI
    F0CA01 CALBERSON YVELINES
    F0CC01 CCIJF
    F0ST01 STANLEY SOLUTIONS DE SECURITE

Discussions similaires

  1. aide pour facture sous php : Notice: Undefined index
    Par le beauceron dans le forum Langage
    Réponses: 3
    Dernier message: 20/08/2012, 00h15
  2. Petite aide pour un index
    Par mandrake57 dans le forum Modélisation
    Réponses: 7
    Dernier message: 20/03/2010, 15h37
  3. Aide pour indexation de mon site web
    Par maxtoucourt dans le forum Référencement
    Réponses: 2
    Dernier message: 02/11/2009, 10h18
  4. Aide pour la mise en place d'un index fulltext
    Par bluecurve dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 13/11/2007, 10h47
  5. Aide pour définir des index (traitement long)
    Par m-mas dans le forum MS SQL Server
    Réponses: 7
    Dernier message: 25/05/2006, 21h39

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