Blog éclectique & sans sujet précis - Mot-clé - ERP<p>Si ça me passe par la tête, si ça n’intéresse que moi, alors c’est peut-être ici. Ou pas.</p>2024-02-13T09:44:49+01:00L'éditeur est le propriétaire du domaineurn:md5:bf83720a7189bba489682d945b972671Dotclear“The Data Warehouse Lifecycle Toolkit” (Second Edition) de Ralph Kimball & courn:md5:16d2a3afeb3413329a843cf6ddf2758f2012-09-04T14:33:00+02:002016-02-25T13:45:14+01:00ChristopheInformatique : l’art du développementbase de donnéesbon sensBusiness ObjectscommunicationcomplexitécourageculturedéveloppementERPexpertiseinformatiquelivres lusoptimisationorganisationperfectionnismeprise de têteréalitéSAPSQLSSIIthéorieténacitévaleuréconomie de l’attentionémerveillement <p><img src="http://ecx.images-amazon.com/images/I/515aQr3H7lL._SL160_OU01_SL90_.jpg" alt="" style="float:right; margin: 0 0 1em 1em;" /></p>
<p>Ouch, ce pavé m’a pris six mois à lire, par parties, et il a dû partager ma table de chevet avec d’autres. Dur de s’y mettre (hé, c’est la théorie de mon boulot !), mais une fois ouvert dur de le lâcher (hé, c’est ma vie ! (enfin, ce que devrait être ma vie dans un monde où on aurait le temps de faire correctement son taf <sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#wiki-footnote-1" id="rev-wiki-footnote-1">1</a>]</sup>)).</p>
<p>Si vous ne savez pas, et ne voulez pas savoir, ce qu’est un <em>datawarehouse</em> (qui dit <em><a href="https://fr.wikipedia.org/wiki/Entrep%C3%B4t_de_donn%C3%A9es">entrepôt de données</a></em> ?), vous pouvez fermer cette page et retourner sur Facebook. En gros, un système décisionnel rassemble, nettoie, coordonne, croise, indexe... dans une même base de données tous les « faits » issus de plusieurs systèmes de production opérationnels (« sources » : CRM, ERP, systèmes de production/logistique/vente/facturation/service après-vente, ou financiers/comptables/RH/marketing..., et la multiplicité des fichiers Excel qui traînent partout), afin de permettre une exploitation homogène, aisée, indépendamment des outils sources, intégrant toutes les règles métier et tous les indicateurs que l’utilisateur désire <sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#wiki-footnote-2" id="rev-wiki-footnote-2">2</a>]</sup>.</p>
<p>Kimball est LA référence du domaine. Franchement, ça se sent dans ce livre bourré de conseils issus de la vie réelle, issus parfois de la politique interne d’entreprise (règles majeures : se trouver un sponsor de poids capable d’imposer aux autres de bosser pour le projet <em>datawarehouse</em> que tout le monde attend sans vouloir lui consacrer une seconde, et qui est transverse, donc <em>a priori</em> l’affaire de personne ; éviter d’avoir des silos séparés par service qui seraient redondants et incohérents ; se méfier de toutes les règles non-écrites et variables d’une personne à l’autre ; chercher les économies et gains auxquels le <em>datawarehouse</em> a participé pour en justifier coût et maintenance).</p>
<p>Bref, tout sauf de la théorie déconnectée. Les performances de l’outil sont un souci constant (comment faire les jointures ?). Les conseils en planning sont de prévoir large <sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#wiki-footnote-3" id="rev-wiki-footnote-3">3</a>]</sup>, et le lecteur est prévenu qu’en soulevant le capot des bases de données source, il aura forcément des surprises <sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#wiki-footnote-4" id="rev-wiki-footnote-4">4</a>]</sup>.</p>
<p>Chaque étape est décrite. En vrac et en en oubliant parce que je n’ai pas envie de relire le sommaire :</p>
<ul>
<li>rassemblement des spécifications (<strong><em>requirements</em></strong>), en se basant sur les <em>process</em> genre vente ou production, et non les services cible (surtout pas de <em>datamarts</em> locaux) ; spécs obtenus des gens du front qu’on cuisinera sur leur vie et attentes ; et pas en leur demandant de fournir les tableaux déjà existants à re-créer, mais quels sont leurs objectifs et « ce qui les empêche de dormir » ;</li>
<li>conception du « <strong>bus d’entreprise</strong> » : les dimensions bien documentées, harmonisées, nettoyées, « conformes » ;</li>
<li>choix des <strong>outils</strong> (longue liste de fonctionnalités dont je ne sais si un produit existe qui les a toutes <sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#wiki-footnote-5" id="rev-wiki-footnote-5">5</a>]</sup>) ;</li>
<li><strong>modélisation</strong> : dimensions à évolution lentes ou pas ; types de tables de fait (là ça m’a éclairci les idées) ;</li>
<li>étapes de l’ETL : notamment en discernant premier chargement et chargement par étape quotidienne par la suite quitte à dupliquer <sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#wiki-footnote-6" id="rev-wiki-footnote-6">6</a>]</sup> ;</li>
<li><strong>nettoyage</strong> des données : typiquement la partie sous-estimée, avec des données qu’on croyait là qui n’y sont, ou pas à la bonne granularité, pas formatées clairement ; bref un nid à surprises <sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#wiki-footnote-7" id="rev-wiki-footnote-7">7</a>]</sup> ;</li>
<li><strong>chargement par <a href="https://fr.wikipedia.org/wiki/Extract_Transform_Load">ETL</a> <sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#wiki-footnote-8" id="rev-wiki-footnote-8">8</a>]</sup></strong> : c’est le plus technique, le plus ingrat, le moins visible ; le challenge réside dans la capacité à charger le <em>datawarehouse</em> dans un temps raisonnable (moins d’une nuit pour les données de la journée écoulée, le temps réel étant une option ruineuse à éviter), en intégrant tout le nettoyage, les calculs, les agrégats, etc. ;</li>
<li><strong>restitutions</strong>, en sachant que 80% des utilisateurs seront « presse-boutons » <sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#wiki-footnote-9" id="rev-wiki-footnote-9">9</a>]</sup> ;</li>
<li><strong>maintenance</strong> : l’équipe ne doit pas être dissoute ou significativement réduite après la mise en production car un <em>datawarehouse</em> n’est jamais fini — à moins que personne ne l’utilise, car justement il doit faire naître des questions qu’on ne posait pas plus tôt <sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#wiki-footnote-10" id="rev-wiki-footnote-10">10</a>]</sup>.</li>
</ul>
<p>Pour chaque étape, il est fourni une liste des livrables.</p>
<p>Dans le décisionnel, j’ai jusque là appris sur le tas en allant direct au front, en maintenant des choses écrites par d’autres, suivi les méthodes de gourous locaux, et pas manipulé de vraiment grosse volumétrie. D’autres collègues avaient d’autres techniques, et je me demandais s’il y avait <em>la</em> bonne méthode, deux méthodes pour deux cas différents, ou juste deux styles différents.</p>
<p>Exemple typique : pour les tables, clé fonctionnelle ou clé synthétique ? Pour les bases opérationnelles, <a href="https://www.coindeweb.net/blogeclectique/index.php?post/2008/05/28/403-cle-primaire-de-substitution-ou-cle-naturelle">y a pas à se poser de question</a>. Pour une base décisionnelle, dénormalisée et alimentée par ETL, c’est plus discutable. Maintenant j’ai vu la lumière : si on cause de perfs on n’échappe pas aux synthétiques, mais pour de la volumétrie réduite, avec les bases de données actuelles, on peut (c’est pas Kimball qui le dit mais moi...) s’épargner cette complexité. Il est possible que la décision soit influencée par l’ETL <sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#wiki-footnote-11" id="rev-wiki-footnote-11">11</a>]</sup>, ensembliste (<a href="http://blog.developpez.com/jmalkovich/p8899/etl/odi-sunopsis/retour-d-experience-sur-sunopsis-odi/">ODI/Sunopsis</a>, mon préféré) ou de flux (cette m... de BODI <sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#wiki-footnote-12" id="rev-wiki-footnote-12">12</a>]</sup>, Informatica...).</p>
<p>Autre grand moment de modélisation : je floconne, ou je floconne pas <sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#wiki-footnote-13" id="rev-wiki-footnote-13">13</a>]</sup> ? Kimball et son équipe sont des adversaires déclarés de la normalisation dans le <em>datawarehouse</em> (l’étoile, rien que l’étoile, ça allège les jointures), et plus le temps passe, plus j’évolue comme ça aussi. Après, faut voir si les grains des tables collent.</p>
<p>Justement, j’ai été conforté par ce que je pensais sur les grains des tables de faits : bien le fixer dès le départ est cardinal et la première chose à faire. Combien de fois me suis-je fait avoir parce que la clé primaire réelle (sous forme d’une composition de clés étrangères dans ce cas) était mal posée, ou était plus là pour le principe qu’autre chose (rassemblement de <em>toutes</em> les clés étrangères de la table !). Et je ne parle pas de contraintes entre faits et dimension totalement absentes. Toutes erreurs qui me coûtent cher en temps de débogage quand j’interviens au niveau de la restitution (univers et rapports Business Objects).</p>
<h3>Bémols</h3>
<ul>
<li>C’est en <strong>anglais</strong>. Dans le métier on n’y coupe pas. On est loin de Shakespeare, c’est très clair et lisible, et il y a quelques touches d’humour par ci-par là.</li>
</ul>
<ul>
<li>Très peu d’exemples concrets (par rapport à la masse d’informations) : dans pas mal de cas, il faudra se raccrocher à sa propre expérience. Je pense à ceux qui ne sont jamais confrontés aux problèmes d’historisation et des dimensions à évolution lente de type 2 et qui ne voient pas forcément de quoi on cause. Bon, cela aurait rajouté pas mal de pages aux plus de 600 (déjà bien denses) mais tout de même.</li>
</ul>
<ul>
<li>La modélisation n’est qu’effleurée, c’est un bon début, mais il va falloir que je continue à creuser le sujet.</li>
</ul>
<ul>
<li>Quant aux comparatifs entre produits sur le marché, il n’y a même pas de tentative. C’est tout juste si le nom d’Excel est glissé furtivement dans un coin, c’est dire. Certes, le marché est pléthorique et évolue vite. J’ai ri jaune en voyant le nombre de fonctionnalités désirables que ne possède absolument pas celui sur lequel je galère la journée. et ce que je vois de la concurrence ne me pousse pas à vouloir m’y jeter, hélas <sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#wiki-footnote-14" id="rev-wiki-footnote-14">14</a>]</sup>.</li>
</ul>
<h3>Moralité</h3>
<p>Ce livre n’est pas pour les débutants dans le décisionnel. Ceux-là auront mieux fait de digérer toute la littérature gratuite et synthétique trouvable en ligne et de se lancer dans de premiers projets d’abord.</p>
<p>Pour les expérimentés, lecture obligatoire.</p>
<h3>Autres avis</h3>
<p>Voir les <a href="http://www.amazon.com/The-Data-Warehouse-Lifecycle-Toolkit/product-reviews/0470149779/ref=lmf_3_rsrsrs0_cm_cr_acr_txt?ie=UTF8&showViewpoints=1" hreflang="en">avis sur Amazon.com</a>, entre autres. Le meilleur comme le pire sont vrais.</p>
<div class="footnotes"><h4>Notes</h4>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#rev-wiki-footnote-1" id="wiki-footnote-1">1</a>] <em>Et où Business Objects serait assez stable pour ne pas exploser tous les plannings de 50%.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#rev-wiki-footnote-2" id="wiki-footnote-2">2</a>] <em>Plus exactement : ce que l’on a pu faire avec les données réellement disponibles en essayant de se rapprocher de ce qu’on a compris de ce qu’il a cru vouloir.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#rev-wiki-footnote-3" id="wiki-footnote-3">3</a>] <em>Ce qui commercialement passe très mal.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#rev-wiki-footnote-4" id="wiki-footnote-4">4</a>] <em>Mon expérience confirme.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#rev-wiki-footnote-5" id="wiki-footnote-5">5</a>] <em>Et en tout cas pas Business Objects.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#rev-wiki-footnote-6" id="wiki-footnote-6">6</a>] <em>J’essaierais même pas de suggérer ça à ma hiérarchie ; faire du boulot en double ça boufferait la marge. Et puis franchement, je ne joue pas avec la volumétrie d’une banque.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#rev-wiki-footnote-7" id="wiki-footnote-7">7</a>] <em>En fait, personne ne sait vraiment ce qu’il y a dans une base de données avant d’y avoir vraiment fouillé. La première fois qu’un 30 février m’a sauté à la gorge, ça a fait tout drôle.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#rev-wiki-footnote-8" id="wiki-footnote-8">8</a>] <em>L’utilité d’un outil ETL dédié, souvent ruineux et toujours délicat, n’est pas immédiate pour qui maîtrise bien le SQL et se dit qu’il s’agit juste de charger des tables. Moi aussi il a fallu me convaincre. Mais quand on doit jongler avec dix bases de trois types différents, un ERP, intégrer plein de fichiers Excel, XML, et suivre à la trace les impacts des modifications des différents schémas, l’outil finalement se révèle ultime. Par contre il faut bien le choisir.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#rev-wiki-footnote-9" id="wiki-footnote-9">9</a>] <em>C‘est vrai, mais d’un autre côté pas mal d’endroits en déduisent que les outils de développement n’ont pas à quitter les mains d’informaticiens ; donc ils ne sont plus faits que pour les informaticiens ; et les </em>power users<em> hors de l’informatique se retrouvent fort démunis et improductifs. Et Business Objects, pourtant ciblant le créneau des utilisateurs capables de s’investir raisonnablement pour faire leurs rapports, devient si lourdingue et complexe qu’une partie doit baisser les bras, quand ce ne sont pas les professionnels eux-mêmes.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#rev-wiki-footnote-10" id="wiki-footnote-10">10</a>] <em>Sur ce point, grosse motivation pour l’équipe de SSII qui voit le « rebond » et grosse surprise pour le client qui voit les demandes de modifications et d’améliorations affluer quand le budget est déjà épuisé. J’ai aussi vu le contraire, l’infocentre pas demandé, construit dans le vide à partir de trois données incohérentes, inutile et pas utilisé. Ou encore celui redondant avec les outils déjà en place et au point.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#rev-wiki-footnote-11" id="wiki-footnote-11">11</a>] <em>L’ETL, on est censé le choisir en fonction du projet et de critères techniques. Arf, je ne l’ai jamais vu choisi qu’en fonction du partenariat avec l’éditeur, de la tarification, ou du fait qu’il soit gratuit.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#rev-wiki-footnote-12" id="wiki-footnote-12">12</a>] <em>Dépare pas chez SAP, cette bouse. Peu pratiqué, mais assez pour savoir que je ne l’aime pas. Même pas fichu de connaître le Ctrl-Z...</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#rev-wiki-footnote-13" id="wiki-footnote-13">13</a>] <em>Floconner, c’est normaliser les dimensions, quand le modèle en étoile voudrait des tables de faits liées directement aux dimensions, sans aller plus loin. Plus les tables sont grosses, plus il est coûteux en jointures de floconner.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#rev-wiki-footnote-14" id="wiki-footnote-14">14</a>] <em>À part un produit d’un éditeur qui n’est pas dans nos partenaires, donc on fait pas.</em></p></div>
https://www.coindeweb.net/blogsanssujetprecis/index.php?post/The-Data-Warehouse-Lifecycle-Toolkit-de-Ralph-Kimball-co#comment-formhttps://www.coindeweb.net/blogsanssujetprecis/index.php?feed/atom/comments/708Les bonnes idées de SAPurn:md5:1f61d4aef9afa936517b4f8bfb96ff342008-10-04T09:11:00+00:002011-06-01T21:01:58+00:00ChristopheInformatique lourdeergonomieERPinformatiqueSAPtotalitarismetravail<p>Contrairement à mon habitude je ne vais pas dire ici que des méchancetés sur SAP vu du côté du développeur. Il y a de bonnes idées en technologie ou en ergonomie à reprendre.</p> <p><em>(Le brouillon de ce billet a attendu publication depuis au bas mot un an et demi. N’ayant plus accès à du SAP, et n’ayant aucune intention de m’y remettre, je renonce à le compléter et le jette dans les index des moteurs de recherche. Le contexte reste le SAP R/3 que j’ai connu en 2006, il faudrait voir les dernières versions.)</em></p>
<p>Comme dirait <a href="http://nobox.fr/">Kooorrg</a>, cet article contient 10% de râlage.</p>
<p>J’ai déjà clamé ici ma déception de SAP et de l’ABAP. Du point de vue du développeur, SAP est un mélange d’archaïsmes des années 80 traînés de force dans les années 90, et l’ABAP est un des langages les plus limités que je connaisse (et pourtant le PL/SQL d’Oracle, le concurrent, n’est pas très <em>sexy</em>) ; sauf peut-être sa version objet, dont la puissance certaine est étouffée par la verbosité du langage et l’<em>over-engineering</em> qu’on y sent à plein nez<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2008/10/04/194-les-bonnes-idees-de-sap#pnote-174-1" id="rev-pnote-174-1">1</a>]</sup>.</p>
<p>Cette fois je vais tenter d’être positif : SAP a ses bons côtés, des bonnes idées qui facilitent la vie et mériteraient d’être reprises chez le concurrent (je ne me souviens pas de les y avoir vues sur Oracle Applications). Cet ERP n’est pas devenu numéro 1 uniquement par sa richesse fonctionnelle et son marketing abrutissant<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2008/10/04/194-les-bonnes-idees-de-sap#pnote-174-2" id="rev-pnote-174-2">2</a>]</sup>.</p>
<h3>Les variantes</h3>
<p>Les variantes constituent un simple gadget au premier abord, mais elles se révèlent en fait très pratiques et font gagner un temps fou. En arrivant dans un écran, l’utilisateur doit choisir parfois une flopée de paramètres : type de commande, fourchette de dates, clients, pays... La saisie faite, il sauvegarde (<em>Ctrl-S</em> directement dans le formulaire de saisie), il donne un nom à la variante, et ce masque de recherche peut alors être réutilisé par la suite.</p>
<p>C’est très utile pour éviter de ressaisir les mêmes valeurs chaque matin ou lors de dizaines de tests identiques en développement. Indispensable également pour cadrer ou modifier ce que l’utilisateur doit entrer, en lui imposant un masque précis sur son écran standard (par défaut ou pas).</p>
<p>(Seul reproche : pour qu’un masque soit utilisable sur une transaction pour tous les utilisateurs, il faut que son nom commence par <code>CUS&</code>, ce n’est pas une case de paramétrage à cocher et pas intuitif...)</p>
<h3>Double clic</h3>
<p>Dans beaucoup d’écran, mais pas tous, un double-clic sur un objet (par exemple un numéro de client) peut mener directement sur l’écran de visualisation dudit client. Très pratique, même si l’hyperlien n’est pas un concept révolutionnaire.</p>
<p>À l’inverse, sous Oracle Applications 11i (fondamentalement un « client lourd » en Java), je voyais en permanence les utilisateurs noter un numéro de commande ou de produit au stylo sur leur sous-main, changer d’écran (voire de « responsabilité », les menus n’intégrant pas tous les écrans accessibles à l’utilisateur), et re-rentrer le numéro sur le masque de recherche. Oracle Appli a rattrapé son retard sur ce point dans les modules récents purement « web ».</p>
<h3>Matchcode</h3>
<p>Non disponible partout, hélas, le <em>matchcode</em> permet de spécifier des critères de recherche beaucoup plus fins qu’une simple fourchette. Par exemple, dans un champ de recherche de numéros de commandes, un <em>matchcode</em> pourrait être « commandes de 500 à 999 sauf de 800 à 803, plus la 1012, moins la 503 ».</p>
<p>Impossible de faire ça simplement avec Oracle Applications à ma connaissance.</p>
<h3>Les mandants</h3>
<p>Une base SAP divise ses tables en « mandants ». Chacun correspond à ce que j’appelle une « vision du monde », à savoir un ensemble de données et (parfois) des objets comme des rapports. Peuvent cohabiter dans un même système un mandant de paramétrage, un mandant de développement sans donnée importante, et un mandant de test avec ses données réalistes.</p>
<p>Un rafraîchissement d’un environnement de développement ou recette depuis la production peut se limiter à écraser les données d’un mandant par les nouvelles sans effacer ce qu’il y a ailleurs (paramétrage…).</p>
<p>Techniquement, ce mandant est la première colonne de chaque clé primaire des tables de la base.</p>
<p>Le concept ne va pas complètement au bout, dans le sens où il existe des objets « intermandants », par exemple les programmes, fonctions... en ABAP. On ne peut donc pas aller jusqu’à avoir une version de développement et une de production d’un programme sur un même système. De plus, certains outils de développement dépendent <em>quand même</em> du mandant (par exemple l’antédiluvien SAPscript).</p>
<h3>Les transports</h3>
<p>Chez le client Oracle Applications où j’ai presté, les mises en production consistaient en une copie manuelle des scripts <em>shell</em> et PL/SQL entre les machine de dév’ et machine de prod’. Avec CVS ou un autre outil le principe serait resté le même : l’intégrité du système est gérée à l’extérieur, et différents systèmes sont techniquement et logiquement isolés (peut-être y a-t-il des outils dédiés ?).</p>
<p>SAP fonctionne par contre par transport d’ordres. C’est le bon côté d’un système qui se veut totalitaire et exige que tout passe par lui : au moins il peut imposer une certaine cohérence et un certain contrôle sur sa propre évolution. De plus, il tient compte de l’existence de plusieurs systèmes SAP les uns à côté des autres.</p>
<p>Les « ordres » regroupent du paramétrage, ainsi que des ensembles de programmes d’un même ensemble ou dépendant les uns des autres. Les ordres tiennent compte des numéros de version, donc un programme peut être dans trois versions différentes sur les environnements de développement, test et production sans mélange. Les utilisateurs autorisés au sein du système approuvent et déclenchent le transfert des ordres entre dév’, recette, prod’...</p>
<p>Les problèmes récurrents sont plus liés au principe qu’à l’outil : dépendances non techniques à vérifier, ordre des transports à maintenir, etc.</p>
<h3>Enregistrements de transactions</h3>
<p>Quand il s’agit d’importer des données, SAP est très ouvert... pourvu que l’on parle son langage ! En clair il faut formater les fichiers sous forme d’<a href="http://help.sap.com/saphelp_40b/helpdata/fr/0b/2a60ef507d11d18ee90000e8366fc2/content.htm">Idocs</a> ou de <a href="http://help.sap.com/saphelp_40b/helpdata/fr/e5/077c824acd11d182b90000e829fbfe/content.htm">fichier Batch Input</a>, un style assez pénible avec des lignes d’entêtes et d’autres de détail. Il y a plusieurs autres outils d’import comme les deux précités ; en fait cela dépend du module et de ce qu’on veut importer, le choix n’a rien d’évident. Comme souvent dans SAP, la méthode dépend de la strate géologique impliquée. Il y a sans doute des <em>web services</em> pleins de XML plus standards à présent dans des développements récents, je doute que cela touche les modules anciens de finance ou de ventes. (D’ailleurs, l’interfaçage avec SAP est une option ruineuse pour nombre de produits de manipulation de données comme les ETL.)</p>
<p>En dernier recours existe un outil antédiluvien mais bien pratique, un bête enregistreur de transactions à l’écran, qui génère un exemple de fichier qui va bien, et que l’on peut utiliser comme modèle pour rejouer des transactions comme si elles étaient entrées manuellement à l’écran, en déclenchant tous les <em>triggers</em>, <em>user exits</em>, etc. Un peu rustique avec quelques côtés sombres, mais ça marche bien et ça a le grand mérite d’exister.</p>
<p>Tous ces outils d’import nécessitent un apprentissage car leur utilisation n’a rien d’intuitive (enfin, peut-être que si après des années sur SAP, je me suis arrêté à 11 mois et demi...). Le cours SAP dédié à ces choses dure une semaine alors qu’un jeu d’API bien foutues ou de tables d’import aurait rempli correctement le besoin. (Comme chez le concurrent Oracle Applications par exemple ; je me suis battu avec ses API et imports à cause de leurs <em>bugs</em> et limites, rarement pour me demander avec quoi importer des données. Seul manque réel d’Oracle Appli : l’outil de simulation d’entrée par les écrans utilisateurs.)</p>
<h3>Cadobonus</h3>
<p><strong>PS</strong> : En bonus, <a href="http://www.sapdesignguild.org/community/design/golden_rules.asp" hreflang="en">10 Golden Rules for Bad User Interface</a> dans un contexte SAP. Des généralités vagues avec lesquelles tout le monde sera d’accord. Il est rigolo de constater que SAP R/3 suit méticuleusement presque toutes ces anti-règles.</p>
<div class="footnotes"><h4>Notes</h4>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2008/10/04/194-les-bonnes-idees-de-sap#rev-pnote-174-1" id="pnote-174-1">1</a>] <em>Comprendre : aucune élégance dans le langage. On doit être à l’opposé de l’<a href="http://en.wikipedia.org/wiki/Objective_C" hreflang="en">Objective C</a> ou de <a href="http://en.wikipedia.org/wiki/Ruby_programming_language" hreflang="en">Ruby</a>. Un langage à l’allemande, façon Panzer.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2008/10/04/194-les-bonnes-idees-de-sap#rev-pnote-174-2" id="pnote-174-2">2</a>] <em>Propagande totalement orientée vers les décideurs et </em>managers<em>, pas du tout vers les développeurs. Quand ces derniers sont concernés par SAP, leur entreprise a </em>déjà<em> décidé de l’acheter, donc ce ne sont pas eux qu’il faut convaincre. Certes le choix du logiciel doit se faire sur ce qu’il apporte à l’entreprise plus que sur sa beauté technique ; d’un autre côté celle-ci a un impact direct sur la lourdeur des coûts de développement, maintenance, formation...</em></p></div>
https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2008/10/04/194-les-bonnes-idees-de-sap#comment-formhttps://www.coindeweb.net/blogsanssujetprecis/index.php?feed/atom/comments/174L’échec du CRM ?urn:md5:7ec424ffc7df88aceae312b0054c99b22007-08-21T07:54:00+00:002011-04-25T21:12:44+00:00ChristopheInformatique lourdeadministrationanticonsumérismebase de donnéesbon senscommunicationcomplexitéCRMdommagedéshumanisationergonomieERPinformatiqueperspectivetravail<p>Grandeur et malheurs d’un <em>buzzword</em> adoré des vendeurs de logiciels.</p> <p>« Les clients se disent victimes des systèmes de GRC<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2007/08/21/366-l-echec-du-crm#pnote-70-1" id="rev-pnote-70-1">1</a>]</sup> » : l’article qui dénonce est ici :
<a href="http://www.lemondeinformatique.fr/actualites/lire-les-clients-se-disent-victimes-des-systemes-de-grc-22970.html">http://www.lemondeinformatique.fr/actualites/lire-les-clients-se-disent-victimes-des-systemes-de-grc-22970.html</a>.</p>
<p>Questions :</p>
<p>- Quelle est la part de l’enquête, et la part de l’envie de faire un titre un peu provocant de la part du journaliste ? Ou d’Accenture, qui a fait l’étude, et qui doit se demander quoi vendre après avoir fait l’apologie de tous les systèmes de gestion à la mode depuis un bout de temps ?</p>
<p>- On accuse le logiciel de dégrader la qualité des prestations de service au client, mais le logiciel est-il coupable quand le processus entier exige souvent des téléopérateurs et -vendeurs sous-traités et payés au lance-pierre qu’ils se comportent comme des robots et ne s’intéressent qu’à réduire au maximum la durée des appels (au pire), ou sont des petits jeunes sans expérience chargés de fourguer au client le maximum de produits (au mieux) ?</p>
<p>- Pour avoir vu fonctionner avec succès deux CRM d’assez près (support interne d’un service après-vente d’un fabricant d’électronique, et télévente de « matière première » à des professionnels de la restauration), je sais que le paramétrage d’un tel monstre est une entreprise titanesque. Les CRM sont <em>vraiment</em> flexibles, mais il faut beaucoup de réflexion et de temps. Évidemment, à l’autre bout, les besoins des clients sont infinis, donc jamais totalement couverts, et immédiats. Je me demande si ces trucs ne sont pas <em>trop</em> compliqués pour être totalement maîtrisés.</p>
<p>- L’une des plaies de notre société est le saucissonnage des tâches : un client a rarement le même interlocuteur de A à Z quand il a un problème, ce qui impose un système de suivi mais augmente les chances de « tomber au travers » et dépersonnalise la relation. Rien de logiciel là-dedans.</p>
<p>- La « relation client » est par définition la part la plus « humaine » de tout ce que peut faire une entreprise. Faut-il vraiment automatiser ça à fond ?</p>
<p>Bref, le problème est-il lié aux logiciels ou à la philosophie actuelle du service au client ?</p>
<div class="footnotes"><h4>Notes</h4>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2007/08/21/366-l-echec-du-crm#rev-pnote-70-1" id="pnote-70-1">1</a>] <em>GRC est le tout aussi imprononçable équivalent français de CRM : </em>Customer Relationship Management<em> ou </em>Gestion de la Relation au Client<em>, au choix. Un concept très à la mode qui a fait la fortune des actionnaires de Siebel, SAP, Salesforce.com et consorts.</em></p></div>
https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2007/08/21/366-l-echec-du-crm#comment-formhttps://www.coindeweb.net/blogsanssujetprecis/index.php?feed/atom/comments/70Service après-venteurn:md5:571cd74a007eb8ab57be8df3293b36192007-04-14T21:00:00+00:002011-03-28T20:15:11+00:00ChristopheBlogger, une aventureAllemagneanticonsumérismeblogcommunicationcoup basdommageDRMdysfonctionnementERPespionnagefoutage de gueuleLéandriMicrosoftMP3OracleperspectiveréseauSAPsaturationSeconde Guerre MondialetravailWindowséconomie<p>Des billets de blog liés à l’actualité, c’est bien, mais il faut assurer le service après-vente et suivre les affaires évoquées.</p> <p>Mini-compilation :</p>
<ul>
<li><a href="http://www.petiteanglaise.com/" hreflang="en">Petite Anglaise</a> a <a href="http://maitre.eolas.free.fr/journal/index.php?2007/03/29/587-affaire-petite-anglaise-la-victoire-de-la-blogueuse">gagné son procès aux prud’hommes pour licenciement abusif</a>. J’avais participé au <a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/07/21/188-google-bombing-pour-petite-anglaise">Google bombing en sa faveur</a>, mais mon billet est à présent redescendu bien bas dans les résultats de Google, éclipsé par tous les articles à ce sujet. Il est vrai aussi que <a href="http://searchenginewatch.com/showPage.html?page=2164611" hreflang="en">Google a récemment pris des mesures contre le bombing</a>.<br /> <a href="http://www.20minutes.fr/article/148757/20070329-Strasbourg-Victoire-pour-Petite-Anglaise.php">Un an de salaire, soit 44 000 euros de dédommagement</a><sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2007/04/14/323-service-apres-vente#pnote-275-1" id="rev-pnote-275-1">1</a>]</sup>, c’est assez sympa ; à ce tarif je veux bien me faire virer tous les ans. Je me sens motivé pour prolonger <a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/07/31/187-les-joies-de-la-ssii-1-angoisse-existentielle">ma série sur la vie en SSII</a> :-)</li>
</ul>
<ul>
<li>Après la FNAC et <a href="https://www.coindeweb.net/blogeclectique/index.php?post/2007/02/28/313-mp3-sans-drm-achetables-en-ligne-enfin">ses (quelques) MP3 non protégés</a>, <a href="http://www.ratiatum.com/news4733_EMI_abandonne_les_DRM_sur_iTunes_quelles_consequences.html">iTunes se lance aussi dans le sans-DRM : EMI a cédé et vendra des morceaux non plombés</a>. L’avenir semble soudain moins sombre dans la guerre contre le verrouillage de la « propriété intellectuelle », même si on est sans doute plus proche du vent qui tourne, style Stalingrad, que de la victoire presque finale, genre chute du Mur de Berlin.</li>
</ul>
<ul>
<li>Même sur des sujets historiques, je me fais rattraper par l’actualité : <a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/04/14/139-fritz-kolbe">Fritz Kolbe, l’Allemand anti-nazi qui renseignait les Américains</a>, a droit à <a href="http://www.telleestmatele.com/article-6269574.html">une émission d’une heure mercredi 11 avril sur Arte</a>. (Et à cause de mon manque de temps, je publie ceci beaucoup trop tard...)</li>
</ul>
<ul>
<li>Vu le temps dont je dispose, non, je ne parlerai pas de la présidentielle. Allez, juste un lien sur un passionnant et affligeant billet de Maître Eolas : <a href="http://www.maitre-eolas.fr/2007/04/03/592-la-machine-a-fabriquer-des-delinquants">comment faire replonger des délinquants rangés des voitures</a> (<strong>2009</strong> : Lien mis à jour).</li>
</ul>
<ul>
<li>Je ne parlerai pas non plus du dernier monstre de Microsoft, sinon pour dire que je l’ai vu rapidement, et que, s’il est moins laid que XP, rien ne m’a frappé qui me donne envie de migrer la machine du boulot, ou d’abandonner mon Mac ou ma Ubuntu.<br />Au passage, le début du rejet des DRM décrit ci-dessus montre, une fois de plus, que Microsoft est incapable de sentir où va tourner le vent de l’histoire informatique : <a href="https://www.coindeweb.net/blogeclectique/index.php?post/2007/02/12/298-analyse-du-cout-de-la-protection-de-contenu-de-windows-vista-par-peter-gutmann">une des principales causes du retard de Vista vient de l’incrustation des DRM à un niveau très profond</a>.</li>
</ul>
<ul>
<li><a href="https://www.coindeweb.net/blogeclectique/index.php?post/2005/09/16/2-hd-dvd-contre-blu-ray">Un an et demi après mon billet sur le sujet</a>, la bataille entre HD DVD et Blu-Ray fait rage, et pour ce que j’en vois, ça a quand même du mal à décoller dans notre coin de la planète. Je laisse filer, ma télé est encore cathodique et le disque dur du magnétoscope plein à ras bord de feuilletons, séries, documentaires, vieux films.</li>
</ul>
<ul>
<li>J’avais fait l’apologie de l’<em><a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/03/18/123-encyclopedie-du-derisoire">Encyclopédie du Dérisoire</a></em> de Bruno Léandri : il continue à sévir dans <em>Fluide Glacial</em>, et je <a href="http://www.fluideboutique.com/cgi-bin/fluide/resultatrech.asp?Option=R">conseille fortement les Hors-Série</a> <em>Votre Entreprise en 2007</em> et <em>Élections 2007</em> (tous publics).</li>
</ul>
<ul>
<li>Je ne devrais plus trop parler de SAP et d’Oracle Applications, je n’y touche plus. Quoique si ça se trouve il me reste des brouillons de billets sur une comparaison d’un point obscur entre ABAP et PL/SQL.</li>
</ul>
<ul>
<li>J’ai plein de billets de <a href="http://www.joelonsoftware.com/" hreflang="en">Spolsky</a> en attente de lecture, donc pas la peine de les lire vous non plus, je les paraphraserai ici dans les quelques années qui viennent.</li>
</ul>
<div class="footnotes"><h4>Notes</h4>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2007/04/14/323-service-apres-vente#rev-pnote-275-1" id="pnote-275-1">1</a>] <em>Nets d’impôts, sans doute, puisque ce sont des dommages et intérêts...</em></p></div>
https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2007/04/14/323-service-apres-vente#comment-formhttps://www.coindeweb.net/blogsanssujetprecis/index.php?feed/atom/comments/275Le rôle des NULL en ABAP et PL/SQLurn:md5:56040aee71c76bee465f8264f3a83dc72007-03-11T22:18:00+00:002011-03-28T19:43:02+00:00ChristopheInformatique : l’art du développementbase de donnéesbugdysfonctionnementdéveloppementERPinformatiquemétainformationparadoxesignifié<p>Comparer le PL/SQL (d’Oracle) et l’ABAP (de SAP) permet de comparer deux stratégies sur un point assez délicat de la programmation informatique : que faire des valeurs <strong>vides</strong> (pas nulles, dans le sens de zéro, mais vides, non renseignées).</p> <p>La plupart des variables manipulées dans un langage informatique ont une valeur par défaut (par exemple zéro pour un nombre, chaîne vide pour une chaîne de caractères...). Or, dans le cadre d’une base de données, certains champs de tables ne sont PAS renseignés : affecter une valeur par défaut à une date est par exemple le meilleur moyen de corrompre les données.</p>
<p>Autre exemple : dans une moyenne de notes d’élèves, un zéro signifiant « pas de note » n’est pas du tout la même chose qu’une bulle pour copie blanche (du moins pour l’élève ; l’ordinateur, lui, s’en contrefiche). On pourrait utiliser un <code>-1</code> pour signifier que la note n’existe pas, mais on complique la logique et le traitement, on mélange « technique » et « fonctionnel » (signification des données). De plus, la table d’à côté contenant des températures qui sont parfois négatives demandera <code>-99999</code> comme valeur « absente » , qui ne conviendra pas à une base manipulant le déficit budgétaire français ou américain, sans parler des valeurs astronomiques utilisées par les astronomes.</p>
<p>Bref, il fallait une <strong>valeur explicitement « absente »</strong>, c’est le sens de <code>NULL</code>. Le SQL l’utilise abondamment, et l’ABAP comme le PL/SQL le connaissent.</p>
<p>Par contre, la manière de le prendre en compte dans le code diffère.</p>
<h3>SQL et PL/SQL</h3>
<p>En SQL et en PL/SQL, le <code>NULL</code> ne peut être comparé à quoi que ce soit ; une comparaison l’impliquant est toujours fausse :</p>
<blockquote><p><code><strong>SELECT</strong> * <strong>FROM</strong> table <strong>WHERE</strong> champ = NULL</code></p></blockquote>
<p>ne renverra jamais rien. Dans ce cas il faut oublier l’égalité et utiliser un opérateur différent (<code>IS NULL</code>).</p>
<p>Plus vicieux, l’exemple suivant ne ramènera jamais les lignes dont la colonne <code>champ</code> est <code>NULL</code> :</p>
<blockquote><p><code><strong>SELECT</strong> * <strong>FROM</strong> table <strong>WHERE</strong> champ <> 4</code></p></blockquote>
<p>alors que dans l’esprit du développeur il s’agissait juste de filtrer une valeur précise - effet de bord du fait que la machine ne peut décider d’une valeur « par défaut » pour cette valeur vide.</p>
<p>Pour parer à ce cela, il faut <strong>explicitement traiter les cas <code>NULL</code></strong> ou affecter une valeur par défaut (fonction <code>NVL</code> sur Oracle) :</p>
<blockquote><p><code><strong>SELECT</strong> * <strong>FROM</strong> table <strong>WHERE</strong> champ IS NULL <strong>OR</strong> champ <>4</code></p></blockquote>
<p>équivaut à :</p>
<blockquote><p><code><strong>SELECT</strong> * <strong>FROM</strong> table <strong>WHERE</strong> NVL(champ, 0) <> 4</code></p></blockquote>
<h3>ABAP</h3>
<p>L’ABAP est techniquement capable de gérer la valeur <code>NULL</code>. Un critère <code>WHERE ... IS NULL</code> est syntaxiquement correct. Mais SAP cherchant à supporter des bases de données anciennes et exotiques, il ne tire pas parti de la fonctionnalité : <strong>toutes</strong> les colonnes de toutes les tables sont flaggées <code>NOT NULL</code>, interdisant la présence d’une valeur <code>NULL</code>, avec une valeur par défaut (un espace<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2007/03/11/234-le-role-des-null-en-abap-et-plsql#pnote-207-1" id="rev-pnote-207-1">1</a>]</sup>, ou zéro).</p>
<p>L’ABAP se voit donc obligé de réémuler la fonctionnalité et introduit la notion d’<strong><code>INITIAL</code></strong>, en fait cette même valeur par défaut, zéro ou espace selon le type !</p>
<p>En conséquence, un critère d’une requête ABAP du genre <code>SELECT ... WHERE champ = valeur</code> est tout le temps valide, même pour une valeur « vide » (en fait par défaut). En informatique de gestion, cela ne gêne pas tant que ça. C’est le point positif.</p>
<p>C’est même particulièrement pratique quand on utilise des <code>SELECT-OPTIONS</code>, à savoir une des astuces sympathiques de SAP : l’utilisateur peut alors choisir comme critère de sélection une liste assez complexe (du genre : « je veux les factures 2000 à 2999, et 7000 à 7999, sauf de 7500 à 7599, et puis les factures 8002 et 9003 en sus. »), et ce critère est stocké dans un <em>range</em>, une simple variable structurée (je passe sur les détails techniques). <br />L’utilisation est basique :</p>
<blockquote><p><code><strong>SELECT</strong> ... <strong>FROM</strong> table <strong>WHERE</strong> ... champ <strong>IN</strong> range.</code></p></blockquote>
<p>Et ça marche aussi quand le <em>range</em> est vide : pas de critère de filtre, donc on veut tout, et la requête ramène tout dans la table interne. Superbe !</p>
<p>Et le piège se referme quand on enchaîne deux critères, qu’au lieu d’un <em>range</em> on utilise une table interne déjà remplie - ou pas :</p>
<p>Par exemple, on choisit une liste de commandes ainsi :</p>
<blockquote><p><code><strong>SELECT</strong> vbeln <strong>FROM</strong> vbak <strong>INTO</strong> t_liste_commande <strong><br />WHERE</strong> ... critère <strong>IN</strong> range.</code></p></blockquote>
<p>Puis on va chercher les lignes de commande en prenant le résultat (<code>t_liste_commande</code>) comme critère, avec la très pratique syntaxe <code>FOR ALL ENTRIES</code><sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2007/03/11/234-le-role-des-null-en-abap-et-plsql#pnote-207-2" id="rev-pnote-207-2">2</a>]</sup> qui permet de balayer une table et d’enchaîner les <code>SELECT</code> sur chaque ligne :</p>
<blockquote><p><code><strong>SELECT</strong> ... <strong>FROM</strong> vbap <strong>INTO</strong> t_liste_lignes<br /><strong>FOR ALL ENTRIES IN</strong> t_liste_commande.</code></p></blockquote>
<p>Si le critère est vide ou pas trop restrictif, on récupère à la première requête, disons dix commandes, et à la deuxième les lignes associées.</p>
<p>MAIS si le critère est trop restrictif, la première requête ne ramène rien... <br />et dans la seconde, le <code>FOR ALL ENTRIES</code>, <em>interprète cette table vide comme une absence de critère de filtrage</em>... et ramène toute la table des lignes de commandes !!! Et il y en a, des lignes de commande dans un SAP qui a quelques années d’existence...<br />Moralité : session figée, mémoire saturée, déconnexion automatique... dans le meilleur des cas<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2007/03/11/234-le-role-des-null-en-abap-et-plsql#pnote-207-3" id="rev-pnote-207-3">3</a>]</sup>.</p>
<p>Ce comportement en fait, est parfaitement cohérent, et inverse de celui d’Oracle. Là où Oracle dit « pensez que cette valeur peut ne pas être remplie », SAP rétorque « votre critère de tri peut ne pas être rempli ». Il faut vérifier ses données sous Oracle, vérifier ses filtres sous SAP. Un <code>IF... ENDIF</code> à rajouter, rien de méchant.</p>
<p>Ah oui, une dernière vacherie pour finir<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2007/03/11/234-le-role-des-null-en-abap-et-plsql#pnote-207-4" id="rev-pnote-207-4">4</a>]</sup> : dans la transaction <code>SE16N</code>, qui, c’est limpide, permet de voir le contenu d’une table de manière assez conviviale<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2007/03/11/234-le-role-des-null-en-abap-et-plsql#pnote-207-5" id="rev-pnote-207-5">5</a>]</sup>, les valeur à <code>INITIAL</code> sont affichées comme étant vides.<br />Ça ne tire pas à conséquence pour les chaînes de caractère, mais voir <em>vide</em> un champ numérique <code>NOT NULL</code> (en fait égal à zéro) fait un petit choc la première fois !</p>
<p><strong>PS</strong> : Je ne sais pas pas, et suis curieux de savoir, comment des langages modernes comme Java, le C++, ObjectiveC ou .net gèrent la chose... Je n’ai jamais eu à les manier en liaison avec des bases de données.</p>
<div class="footnotes"><h4>Notes</h4>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2007/03/11/234-le-role-des-null-en-abap-et-plsql#rev-pnote-207-1" id="pnote-207-1">1</a>] <em>Un espace et non une chaîne vide, car pour la base de donnée Oracle généralement sous-jacente, une chaîne vide '' est équivalente à <code>NULL</code> ! Ce qui n’est pas le cas d’autres bases, par exemple PostgreSQL, qui distingue <code>''</code> et <code>NULL</code> - ça surprend au premier changement de système.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2007/03/11/234-le-role-des-null-en-abap-et-plsql#rev-pnote-207-2" id="pnote-207-2">2</a>] <em>Enfin, <a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/11/16/252-par-paquets-de-5">j’en ai déjà dit ici pas mal de mal, sur le plan des perfs</a>.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2007/03/11/234-le-role-des-null-en-abap-et-plsql#rev-pnote-207-3" id="pnote-207-3">3</a>] <em>Dans le pire des cas, la production est bloquée par ce programme bogué, et le rythme cardiaque du consultant atteint son maximum annuel.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2007/03/11/234-le-role-des-null-en-abap-et-plsql#rev-pnote-207-4" id="pnote-207-4">4</a>] <em>Je n’avais pas encore dit de mal de SAP dans ce billet, ça manquait.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2007/03/11/234-le-role-des-null-en-abap-et-plsql#rev-pnote-207-5" id="pnote-207-5">5</a>] <em>Sous forme d’un bête tableau qu’on peut </em>scroller<em>, dont on peut agrandir ou réduire les colonnes... Le summum de la convivialité SAP ! À coder, c'est moins drôle.</em></p></div>
https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2007/03/11/234-le-role-des-null-en-abap-et-plsql#comment-formhttps://www.coindeweb.net/blogsanssujetprecis/index.php?feed/atom/comments/207Initialiser tu n’oublieras pas !urn:md5:c8fecc474a35cdcefe10e9f63248b7252006-12-19T13:47:00+00:002010-11-19T21:38:17+00:00ChristopheInformatique lourdeabominationdommagedéterminismedéveloppementERPfoutage de gueulegaspillagehaineincohérenceinformatiquemétainformationOracleperfectionnismeprise de têtesabotageSAPSQLsécuritétravail<p>Bien programmer c’est en partie bien initialiser pour bâtir sur de bonnes bases. Évidemment, l’ABAP ne peut pas laisser passer ça !</p> <p>Une des raisons pour lesquelles l’ABAP m’énerve est que ce langage me met des bâtons dans les roues lorsque je cherche à réutiliser mes habitudes de programmation en mode « défensif ».</p>
<p>Prenons un exemple où l’on balaye une innocente table (disons les lignes d’une facture) ; le curseur est nommé <code>x</code> et on veut un <code>compteur</code> qui somme le contenu de la colonne <code>un_autre_champ</code> (un prix par exemple), <em>plus</em> une valeur calculée arbitrairement (par exemple une taxe) si la colonne <code>un_champ</code> prend une valeur quelconque. Cela donne :</p>
<p>En PL/SQL (langage d’Oracle Applications, entre autres) :</p>
<blockquote><p>.<code><strong>FOR</strong> x IN (SELECT * FROM matable) LOOP </code><br />
.<code> <strong>DECLARE</strong> </code><br />
.<code> v VARCHAR(2) := 0 ; </code><br />
.<code> <strong>BEGIN</strong> </code><br />
.<code> <strong>IF</strong> x.un_champ = ... THEN </code><br />
.<code> v = c_une_valeur ; </code><br />
.<code> <strong>END IF</strong> ; </code><br />
.<code> compteur = compteur + v + x.un_autre_champ ; </code><br />
.<code> <strong>END</strong> ; </code><br />
.<code><strong>END LOOP</strong> ; </code><br /></p></blockquote>
<p>En ABAP (langage de SAP exclusivement) :</p>
<blockquote><p>.<code><strong>SELECT</strong> * FROM matable INTO x.</code><br />
.<code> <strong>DATA</strong> v TYPE c VALUE '0'.</code><br />
.<code> <strong>IF</strong> x-un_champ = ... .</code><br />
.<code> v = c_une_valeur.</code><br />
.<code> <strong>ENDIF</strong>.</code><br />
.<code> compteur = compteur + v + x-un_autre_champ.</code><br />
.<code><strong>ENDSELECT</strong>. </code> " <em>Fin de la boucle</em></p></blockquote>
<p>Ces deux codes, bien que fort semblables aux différences syntaxiques superficielles près, ne feront en fait pas la même chose. Comme j’ai dit, on ne recalcule <code>v</code> que dans certains cas.</p>
<p>En PL/SQL, la déclaration de <code>v</code> <em>à l’intérieur</em> de la boucle (donc comme variable la <em>moins globale</em> possible), permet de redéclarer et réinitialiser à zéro <code>v</code> à chaque tour de boucle.</p>
<p>En ABAP, la combine ne fonctionne pas. Le code ci-dessus ne réinitialisera <em>pas</em> <code>v</code> à 0. Il n’y a aucune erreur due au fait que j’ai redéclaré ma variable à chaque tour de boucle. Entre deux tours, <code>v</code> gardera sa valeur !</p>
<p>On peut corriger de mille manières, par exemple en prévoyant une deuxième branche <code>ELSEIF</code>, qui effectue <code>v = 0</code>. <br />Ou bien, tout bêtement, en réinitialisant à chaque début de boucle : <code>CLEAR v.</code> En ABAP, c’est pas plus difficile que cela.</p>
<p>Mais. Ici il n’y a qu’<em>une</em> variable. <br />Dans la réalité des dizaines de variables, compteurs, structures, tableaux, déclarés un peu n’importe où, se partagent l’attention du programmeur. Je suis un ferme partisan de l’initialisation au moment de la déclaration, de la durée de vie la plus minimaliste possible des variables, un ennemi des variables globales et un accro de la réduction du <em><a href="http://www.digital-web.com/articles/variable_scope_for_new_programmers/" hreflang="en">scope</a></em>. Une variable qui n’existe pas ne me gênera jamais.</p>
<p>L’ABAP n’est pas un compilateur très coopératif pour ce genre de programmation. Les variables restent en général globales à un (sous-)programme, et les orgies de <code>CLEAR</code> parsèment les boucles. Je vois ressurgir des classes entières de bugs que je ne connaissais pas en PL/SQL. Et, je le redis, le PL/SQL n’a rien de très <em>sexy</em> ou avancé, c’est juste un langage bien foutu pour son boulot (fortement inspiré du Pascal, ce qui me plaît).</p>
<p><strong>NB</strong> : L’exemple ci-dessus néglige le fait que sous Oracle un ordre SQL aurait suffit, même pas la peine de dégainer le PL :<br /><code>SELECT SUM(un_autre_champ + DECODE (un_champ, ..., c_une_valeur) ) FROM ma_table</code> ou une autre astuce de la même veine. Je ne pense pas que ce soit facilement possible en ABAP pur - qu’on me corrige si je me trompe.</p>
<p>(<strong>Dernière minute</strong> : Et en plus, il semblerait que <a href="http://www.panopticoncentral.net/archive/2006/03/28/11552.aspx" hreflang="en">le Visual Basic (nouvelle version) soit aussi victime de ce problème</a> ! Différence entre scope et durée de vie d’une variable, dit l’auteur. En tout cas c’est source de bugs...)</p>https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/12/19/210-initialiser-tu-n-oublieras-pas#comment-formhttps://www.coindeweb.net/blogsanssujetprecis/index.php?feed/atom/comments/188Par paquets de 5urn:md5:da931c4493743ea43137bae625a401a62006-11-16T22:17:00+00:002010-11-16T06:22:02+00:00ChristopheInformatique lourdeabominationbase de donnéesdéveloppementERPfoutage de gueulegaspillagehaineinformatiqueoptimisationOracleprise de têtesabotageSAPSQLtravail<p>Une fois de plus, l’ABAP de SAP me sabote mes requêtes soigneusement mitonnées.</p> <p>Ce n’est pas parce que <a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/10/19/255-demission">la perspective de me débarrasser bientôt de SAP</a> se profile nettement à l’horizon que mes critiques vont se tarir.<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/11/16/252-par-paquets-de-5#pnote-223-1" id="rev-pnote-223-1">1</a>]</sup>. La semaine dernière j’ai découvert une nouvelle manière de l’ABAP de fusiller le travail de la base Oracle en-dessous de lui.</p>
<p>Un exemple concret en ventes : je recherche quelques articles (premier <code>SELECT</code> sur la table <code>MARA</code>) et je veux afficher la liste des commandes portant sur ces articles. Le résultat ressemble à ça :</p>
<p><img src="https://www.coindeweb.net/blogeclectique/images/erp/abap-forallentries/liste_resultat.png" alt="Petite liste" style="display:block; margin:0 auto;" title="Liste d’articles avec les commandes qui vont avec." /></p>
<p>Pour obtenir ceci, je peux :</p>
<ul>
<li>soit faire un <code>SELECT</code> sur la table <code>VBAP</code> pour <em>chaque</em> article précédemment récupéré (méthode bovinement simple, fiable, très efficace si le but est de faire s’effondrer la base de données par des centaines ou des milliers de requêtes en rafale) ;</li>
<li>soit tenter de récupérer toutes les commandes concernées <em>en bloc</em> : la base recherchera d’un coup, optimisera son parcours de diverses manières (ne pas analyser 10 000 fois la même requête<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/11/16/252-par-paquets-de-5#pnote-223-2" id="rev-pnote-223-2">2</a>]</sup>, récupérer des blocs contigus, choisir un index plutôt qu’un autre...).</li>
</ul>
<p>La deuxième manière est un chouilla plus complexe (car on récupère en bloc un tableau des commandes voulues, qu’il faudra manipuler ensuite) mais monstrueusement plus efficace. <br />Si on utilise Oracle directement via la SQL ou le PL/SQL, <a href="http://tkyte.blogspot.com/2006/10/slow-by-slow.html" hreflang="en">on tente au maximum de tout regrouper en un seul ordre SQL</a>, ou on utilise les <a href="http://www.oracle.com/technology/oramag/oracle/03-sep/o53asktom.html" hreflang="en">ordres BULK</a>. <br />Si on est contraint de passer par l’ABAP, on utilise <code>FOR ALL ENTRIES</code><sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/11/16/252-par-paquets-de-5#pnote-223-3" id="rev-pnote-223-3">3</a>]</sup>.</p>
<p>Concrètement, cela donne ce qui suit. Noter qu’en ABAP un <code>SELECT</code>/<code>ENDSELECT</code> est une boucle sur les lignes ramenées.</p>
<blockquote><p><code><em>*</em></code><br />
<code><em>* Report Z_FAE_TEST </em></code><br />
<code><em>* </em></code><br />
<code><em>*</em></code><br />
<code><em>* But : démonstration d utilisation basique de FOR ALL ENTRIES </em></code><br />
<code><em>* Recherche de quelques articles et affichage des commandes liées à </em></code><br />
<code><em>* ces articles. On aurait pu faire une simple jointure mais on passera</em></code><br />
<code><em>* par une table interne (un tableau) qui ontient ces commandes.</em></code><br />
<code><em>*</em></code><br />
<br />
<code><strong>REPORT Z_FAE_TEST</strong> .</code><br />
<br />
<code><em>* vbap est la table des commandes, et la déclaration</em></code><br />
<code><em>* suivante permet de ne pas déclarer des variables temporaires</em></code><br />
<code><em>* pour la parcourir</em></code><br />
<code>TABLES: vbap.</code><br />
<br />
<code><em>* Structure de table simple avec juste un champ article</em></code><br />
<code>TYPES: BEGIN OF article,</code><br />
<code> matnr TYPE matnr, " type prédéfini : un article</code><br />
<code> END OF article.</code><br />
<br />
<code><em>* Table des articles</em></code><br />
<code><strong>DATA</strong>: tab_articles TYPE TABLE OF article.</code><br />
<br />
<code><em>* Variable tampon car impossible de faire cette operation</em></code><br />
<code><em>* directement au sein du SQL ci-dessous.</em></code><br />
<code>DATA: date_min TYPE datum.</code><br />
<br />
<code><em>* Récupérer les articles créés dans les 200 derniers jours</em></code><br />
<code>date_min = sy-datum - 200.</code><br />
<br />
<code><strong>SELECT</strong> matnr <strong>FROM</strong> mara</code><br />
<code><strong>INTO TABLE</strong> tab_articles</code><br />
<code><strong>WHERE</strong> ersda > date_min.</code><br />
<code>.</code><br />
<br />
<br />
<code><em>* Pour tous ces articles, afficher</em></code><br />
<code><em>* toutes les commandes existantes</em></code><br />
<br />
<code><strong>SELECT</strong> * <strong>FROM</strong> vbap</code><br />
<code><em>* Prendre articles dans table interne précédente</em></code><br />
<code><strong>FOR ALL ENTRIES</strong> IN tab_articles</code><br />
<code><em>* Jointure sur code article</em></code><br />
<code><strong>WHERE</strong> vbap~matnr = tab_articles-matnr</code><br />
<code>.</code><br />
<br />
<code><em>* Affiche article/commande/poste</em></code><br />
<code> WRITE :/ vbap-matnr, vbap-vbeln, vbap-posnr .</code><br />
<br />
<code><strong>ENDSELECT</strong>.</code><br /></p>
<p></p></blockquote>
<p>Quand on lit ceci, et qu’on connaît un peu Oracle, on se dit que l’ABAP sur ce point n’est pas trop mal foutu, et qu’il a même eu un temps d’avance sur l’Oracle « pur » d’avant l’implémentation de <code>BULK COLLECT</code>, qui forçait à tout fusionner en un seul ordre SQL si l’on voulait éviter les boucles.</p>
<p>On se dit que l’ABAP doit lui-même écrire l’ordre SQL qui va bien. Ou qu’il rédige une clause <code>WHERE</code> de centaines de lignes avec les flopées de valeurs possibles.</p>
<p>Mais non.</p>
<p>Le SQL que SAP demande à Oracle d’exécuter servilement se présente ainsi (transaction <code>ST05</code> sous SAP) :</p>
<p><img src="https://www.coindeweb.net/blogeclectique/images/erp/abap-forallentries/sql_trace.png" alt="Trace SQL" style="display:block; margin:0 auto;" /></p>
<p>Il s’agit bien d’un bête <code>SELECT</code> avec une condition sur... <strong>CINQ valeurs possibles</strong>. Ceci répété x fois avec des valeurs différentes.<br />SAP <strong>fait donc exécuter à Oracle la boucle même que l’on cherchait à éviter à la main</strong>. Le seul avantage est que cette recherche se fait par paquet de cinq lignes. C’est déjà mieux que rien mais <a href="http://asktom.oracle.com/pls/ask/f?p=4950:8:::::F4950_P8_DISPLAYID:73891904732164" hreflang="en">on est loin du Saint Graal de l’instruction SQL unique</a>.</p>
<p>Il existe un moyen de rentabiliser un peu plus chaque requête en passant à des bloc de vingt valeurs (rajouter le <em>hint</em> <code>%_HINTS ORACLE '&max_blocking_factor 20&'</code>), sans que j’en connaisse l’efficacité réelle.</p>
<p>Pourquoi faire simple (un bête curseur Oracle qui parcourt les lignes ramenées par paquets de quelques dizaines, avec un plan d’exécution mitonné pour l’intégrale du <em>recordset</em> à récupérer) quand on peut faire compliqué ?</p>
<div class="footnotes"><h4>Notes</h4>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/11/16/252-par-paquets-de-5#rev-pnote-223-1" id="pnote-223-1">1</a>] <em>Sisi, un jour, je tenterai de faire un billet sur les gadgets sympa de SAP et de l’ABAP. Il y en a. <strong>Ajout de 2008</strong> : <a href="https://www.coindeweb.net/blogeclectique/index.php?post/2008/10/04/194-les-bonnes-idees-de-sap">C’est fait !</a></em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/11/16/252-par-paquets-de-5#rev-pnote-223-2" id="pnote-223-2">2</a>] <em>Le plus terrible est de générer des <a href="http://www.akadia.com/services/ora_bind_variables.html" hreflang="en">requêtes en dynamique, réellement différentes, sans variables bind</a>.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/11/16/252-par-paquets-de-5#rev-pnote-223-3" id="pnote-223-3">3</a>] <em>Et c’est un des rares et précieux exemples de <a href="http://fr.wikipedia.org/wiki/Sucre_syntaxique">sucre syntaxique</a> de ce langage fossile.</em></p></div>
https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/11/16/252-par-paquets-de-5#comment-formhttps://www.coindeweb.net/blogsanssujetprecis/index.php?feed/atom/comments/223Des millions de lignes à travers le millefeuilleurn:md5:e0087cac7dae17633e64eca1d6d9ca812006-10-14T12:47:00+00:002014-02-26T11:06:21+00:00ChristopheInformatique lourdeabominationautodestructionbase de donnéescomplexitédommagedysfonctionnementdéveloppementERPexpertisegaspillageinformatiqueoptimisationOracleorganisationprovocationsabotageSAPsaturationSQLtravailténacité<p>Ou : « Du danger des outils qui s'empilent les uns sur les autres : autopsie d’un plantage en production. »</p> <p>Prenons un <a href="http://solutions.journaldunet.com/0208/020827_bi_panorama1.shtml">ETL</a>, outil chargé d’extraire bêtement des données d’un gros progiciel d’entreprise, <a href="https://www.coindeweb.net/blogsanssujetprecis//index.php?post/2006/03/04/87-les-joies-de-l-erp-et-du-crm-i">SAP</a> pour ne pas le nommer. SAP lui-même s’appuie sur une base de données <a href="http://www.oracle.com/lang/fr/database/index.html">Oracle</a>. L’ETL pourrait en principe attaquer les données directement au niveau Oracle, mais <strong>SAP impose que l’on passe par lui</strong><sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/10/14/246-des-millions-de-lignes-a-travers-le-millefeuille#pnote-217-1" id="rev-pnote-217-1">1</a>]</sup>.</p>
<p>De ces trois outils, chacun utilise une variante de la <em>lingua franca</em> des bases de données, le <a href="http://www.commentcamarche.net/sql/sqlintro.php3">SQL</a> : Oracle connaît le PL/SQL (langage efficace et sans chichis que j’ai appris à apprécier), SAP utilise l’ABAP (mélange de Cobol et de SQL limité par sa tendance à vouloir s’appuyer sur plusieurs bases de données différentes sans en exploiter une à fond), et l’ETL définit ses requêtes sous forme graphique avec des morceaux de pseudo-SQL<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/10/14/246-des-millions-de-lignes-a-travers-le-millefeuille#pnote-217-2" id="rev-pnote-217-2">2</a>]</sup>.</p>
<h3>Besoin</h3>
<p>Au départ, le besoin était tout simple : une <strong>bête jointure de deux tables</strong> sur les « documents article », et récupération des lignes où au moins une de trois dates potentielles était dans une certaine fourchette.</p>
<p>Du côté de l’ETL, le développeur a exprimé cela ainsi :</p>
<blockquote><p>Joli graphique joignant les tables <code>MKPF</code> (en-têtes) et <code>MSEG</code> (lignes)<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/10/14/246-des-millions-de-lignes-a-travers-le-millefeuille#pnote-217-3" id="rev-pnote-217-3">3</a>]</sup>, <br />et clause de filtrage définie ainsi :<br /> <br />
<code>MKPF.MBLNR = MSEG.MBLNR</code> (jointure)<br />
<code>AND</code><br />
<code>(</code><br />
<code> ( MKPF.CUPDT >= $PARAM2 AND MKPF.CPUDT <= $PARAM1 )</code><br />
<code>OR ( MKPF.AEDAT >= $PARAM2 AND MKPF.AEDAT <= $PARAM1 )</code><br />
<code>OR ( MKPF./BEV2/ED_AEDAT >= $PARAM2 AND MKPF./BEV2/ED_AEDAT <= $PARAM1 )</code><br />
<code>)</code></p></blockquote>
<h3>Boum !</h3>
<p>L’ETL s’adresse donc à SAP, et génère pour cela à la volée un programme ABAP ; le noyau SAP traduit cette requête dans le SQL d’Oracle, lequel renvoie les données au programme ABAP, dont la sortie est renvoyée à l’ETL.</p>
<p>Après quelques mois en production, ce programme a un soir littéralement explosé (le noyau de SAP refusa de lui allouer plus de mémoire, considérant qu’avec plusieurs gigaoctets il abusait déjà).</p>
<p>En fouillant on découvre déjà que la volumétrie remontant dans SAP se compte en <strong>millions de lignes</strong> (tables de mouvements de stocks d’une entreprise de belle taille sur plusieurs années), et qu’aucune des colonnes de filtrage n’est indexée dans la base de donnée. Le résultat final que recueille l’ETL ne compte cependant que peu d’enregistrements.</p>
<p>Dans le contexte présent d’un <em>cluster</em> de machines bien burnées, Oracle exécute ce double <em>full scan</em> en peu de temps — pas assez pour qu’on ait besoin de demander à un chef d’imposer à un administrateur système réticent de rajouter des index lourds sur des tables très sollicitées<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/10/14/246-des-millions-de-lignes-a-travers-le-millefeuille#pnote-217-4" id="rev-pnote-217-4">4</a>]</sup>. Ce n’est pas un <del>simple</del> classique problème de performances.</p>
<p>Le programme ABAP généré par l’ETL ressemble à ceci (je simplifie) :</p>
<blockquote><p><code><strong>SELECT</strong></code><br />
<code> MSEG9~MBLNR</code> (champs) <br />
<code> MSEG9~MJAHR</code><br />
<code> MSEG9~ZEILE</code><br />
<code> ...</code><br />
<code><strong>INTO</strong> (MSEG9MBLNR,</code> (stockage de la ligne dans des variables temporaires)<br />
<code> MSEG9MJAHR,</code><br />
<code> MSEG9ZEILE...)</code><br />
<code><strong>FROM</strong> MSEG AS MSEG9</code><br />
<code> <strong>INNER JOIN</strong> MKPF AS MKPF9</code> (jointure) <br />
<code> <strong>ON</strong> MKPF9<a></a>MBLNR </code><br />
<code>.</code><br />
...<br />
<code><strong>IF</strong> ( ( ( ( MKPF9CPUDT <= $PARAM1 )</code> (clause de filtrage)<br />
<code> OR ( MKPF9AEDAT <= $PARAM1 ) )</code><br />
<code> OR ( MSEG9/BEV2/ED_AEDAT <= $PARAM1 ) )</code><br />
<code> AND ( ( ( ( MKPF9CPUDT >= $PARAM2 )</code><br />
<code> OR ( MKPF9AEDAT <= $PARAM1 ) )</code><br />
<code> OR ( MSEG9/BEV2/ED_AEDAT <= $PARAM1 ) )</code><br />
<code> AND ( ( ( ( MKPF9CPUDT <= $PARAM1 )</code><br />
<code> OR ( MKPF9AEDAT >= $PARAM2 ) )</code><br />
<code> OR ( MSEG9/BEV2/ED_AEDAT <= $PARAM1 ) )</code><br />
<code> AND ( ( ( ( MKPF9CPUDT >= $PARAM2 )</code><br />
<code> OR ( MKPF9AEDAT >= $PARAM2 ) )</code><br />
<code> OR ( MSEG9/BEV2/ED_AEDAT <= $PARAM1 ) )</code><br />
<code> AND ( ( ( ( MKPF9CPUDT <= $PARAM1 )</code><br />
<code> OR ( MKPF9AEDAT <= $PARAM1 ) )</code><br />
<code> OR ( MSEG9/BEV2/ED_AEDAT >= $PARAM2 ) )</code><br />
<code> AND ( ( ( ( MKPF9CPUDT >= $PARAM2 )</code><br />
<code> OR ( MKPF9AEDAT <= $PARAM1 ) )</code><br />
<code> OR ( MSEG9/BEV2/ED_AEDAT >= $PARAM2 ) )</code><br />
<code> AND ( ( ( ( MKPF9CPUDT <= $PARAM1 )</code><br />
<code> OR ( MKPF9AEDAT >= $PARAM2 ) )</code><br />
<code> OR ( MSEG9/BEV2/ED_AEDAT >= $PARAM2 ) )</code><br />
<code> AND ( ( ( MKPF9CPUDT >= $PARAM2 )</code><br />
<code> OR ( MKPF9AEDAT >= $PARAM2 ) )</code><br />
<code> OR ( MSEG9/BEV2/ED_AEDAT >= $PARAM2 ) ) ) ) ) ) ) ) ).</code><br />
<br />
... (sauvegarde de la ligne dans une table interne qui sera envoyée à l’ETL)<br />
<br />
<code><strong>ENDIF</strong>.</code><br />
<br />
<code><strong>ENDSELECT</strong>.</code> (fin du parcours des lignes ramenées)</p></blockquote>
<p>J’ignore pourquoi la clause <code>IF</code> est si tourmentée, mais elle est mathématiquement équivalente à celle d’origine (une des trois dates doit être dans la fourchette demandée).</p>
<p>Le point à retenir est que <strong>ce <code>IF</code> est <em>hors</em> de la requête</strong>. Chacune des millions de lignes de la table passe dans ce <code>IF</code> ! <br />On objectera naïvement que de toute manière, faute d’index, il n’y a pas d’autre moyen que ce fastidieux méga-test.</p>
<p>Mais l’important est <strong>l’endroit où ce test s’effectue</strong> : les millions de lignes sont récupérées par la base Oracle, en sortent, entrent dans le noyau SAP (potentiellement une autre machine), et c’est le processeur ABAP qui se charge des tests sur les dates.</p>
<h3>Reformulation</h3>
<p>Le changement du programme ABAP est assez basique : j’ai déplacé la clause de filtrage <em>dans</em> la requête ABAP, espérant ainsi que SAP traduira cela à Oracle en une seule requête avec la clause de filtrage. (Et pour être propre on réécrit lisiblement la clause, et on rajoute <code>MJAHR</code> dans la jointure, qui manquait sans que cela gêne en pratique.)</p>
<blockquote><p><code><strong>SELECT</strong>...</code><br />
<code><strong>FROM</strong> MSEG AS MSEG9</code><br />
<code> <strong>INNER JOIN</strong> MKPF AS MKPF9</code><br />
<code> <strong>ON</strong> ( MKPF9<a></a>MBLNR</code> <br />
<code> AND MKPF9<a></a>MJAHR )</code><br />
<code><strong>WHERE</strong> ( MKPF9~CPUDT BETWEEN $PARAM2 AND $PARAM1 )</code><br />
<code> OR ( MKPF9~AEDAT BETWEEN $PARAM2 AND $PARAM1 )</code><br />
<code> OR ( MSEG9~/BEV2/ED_AEDAT BETWEEN $PARAM2 AND $PARAM1 )</code></p></blockquote>
<p>Oracle fait toujours un double <em>full scan</em>, le temps d’exécution est très proche, mais les lignes filtrées ne sortent même pas de la couche SQL, Oracle les jette à peine délivrées par le disque dur. On a évité à des gigaoctets de données de traverser au moins deux couches du mille-feuilles et d’occuper de la précieuse mémoire.</p>
<p>Pour les curieux, le SQL généré par SAP après la modification est basique :</p>
<blockquote><p><code> <strong>SELECT</strong> </code><br />
<code> T_00 . "MBLNR" , T_00 . "MJAHR" , T_00 . "ZEILE" , ...</code><br />
<code> <strong>FROM</strong> </code><br />
<code> "MSEG" T_00 , "MKPF" T_01</code><br />
<code> <strong>WHERE</strong> </code><br />
(jointure)<br />
<code> ( T_01 . "MANDT"<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/10/14/246-des-millions-de-lignes-a-travers-le-millefeuille#pnote-217-5" id="rev-pnote-217-5">5</a>]</sup> = :A0 AND T_01 . "MBLNR" = T_00 . "MBLNR" </code><br />
<code> AND T_01 . "MJAHR" = T_00 . "MJAHR" ) AND T_00 . "MANDT" = :A1</code><br />
(filtre sur les dates)<br />
<code> AND ( T_01 . "CPUDT" BETWEEN :A2 AND :A3</code><br />
<code> OR T_01 . "AEDAT" BETWEEN :A4 AND :A5</code><br />
<code> OR T_00 . "/BEV2/ED_AEDAT" BETWEEN :A6 AND :A7 </code><br />
<code> ) </code></p></blockquote>
<h3>Moralité</h3>
<p>Cet exemple est inhabituel : le développeur comme l’administrateur d’une base cherchent en général à limiter les <em>full scans</em> sur des tables aussi volumineuses, et rajoutent des index (mais il faut contrebalancer avec le coût en disque et en maintenance). On a ici la conjonction de plusieurs problèmes :</p>
<ul>
<li><strong>pas d’index</strong> sur de grosses tables (quoique, reconnaissons-le, des stats rafraîchies ont mené à un parcours un peu différent en joignant les tables par leur clé commune ; dans le cas d’un parcours complet des tables, cela n’est pas forcément une bonne chose, et on ne change rien au problème de la volumétrie) ;</li>
<li>un <strong>ETL qui n’a pas le droit de s’adresser directement à Oracle</strong>, alors qu’il connaît très bien son langage (un bon ETL est polyglotte : Oracle dans toutes ses variantes, Sybase, MS SQL Server, DB2...) ;</li>
<li>cet ETL (ou plutôt son <em>plug-in</em> pour SAP) commet une erreur stupide en <strong>séparant requête et filtrage (bug d’optimisation)</strong> <br />(<strong>Ajout de 2014</strong> : Cet ETL, je l’utilise encore des années après, et même dans des incarnations plus modernes il reste le plus stupide et le moins agréable de tous ceux que j’ai pu manipuler — mais il est vendu par SAP) ;</li>
<li>le compilateur ABAP n’est pas assez fûté pour repérer le problème et demande à Oracle le contenu complet de <code>MSEG</code> et <code>MKPF</code> ;</li>
<li>le compilateur ABAP semble <strong>incapable de gérer efficacement des paquets de plusieurs gigaoctets</strong>, il semble tout vouloir traiter d’un bloc, alors qu’Oracle traite ses données par paquets maniables de quelques dizaines de lignes (j’aimerais des détails, cette limite de SAP m’étonne) : le même bug ne serait pas apparu en PL/SQL ;</li>
<li>ajoutons un effet pervers dû au dimensionnement imposant des machines concernées : le problème n’est apparu ni en développement ni en recette (de plus ces bases sont anciennes, très anciennes, et je le déplore tous les jours), mais en production après un certain temps, quand les tables ont dépassé une certaine taille.</li>
</ul>
<p>Comme toutes les grandes catastrophes<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/10/14/246-des-millions-de-lignes-a-travers-le-millefeuille#pnote-217-6" id="rev-pnote-217-6">6</a>]</sup>, ce problème naît d’une accumulation de plusieurs bugs, et non d’un seul.</p>
<h3>Effet mille-feuilles et communication</h3>
<p>Les problèmes de communication entre programmes et la génération automatique de code sont courants, mais le « mille-feuilles » est une bonne pratique en programmation : vive la séparation des tâches entre modules spécialisés ! Cf couches OSI, TCP/IP, le protocole X, etc.</p>
<p>Mais ce n’est pas le cas ici : trois éléments ont <strong>chacun leur langage pour exprimer ce qui est fondamentalement une requête SQL</strong> ; la <strong>traduction n’est pas parfaite</strong> ou limitée, et n’utilise en tout cas pas toutes les possibilités de l’outil sous-jacent (Oracle).</p>
<p>On n’a pas <em>délégation</em> du travail et encapsulation des détails propres à un niveau qui ne concernent pas les autres (comme entre les différences couches de TCP/IP ou X), mais <em>réécriture</em> de consignes avec réinterprétation au passage à chaque étape : à la syntaxe près, la requête de l’ETL est strictement la même que le SQL d’Oracle, les couches qui font le boulot sont en dessous (dans le noyau Oracle).</p>
<h3>Analogie</h3>
<p>Cette histoire me rappelle furieusement le fonctionnement d’un service informatique au sens large, où la définition d’un développement à effectuer passe de l’utilisateur au support au fonctionnel interne au fonctionnel externe à l’analyste présent chez le client au chef de projet externe au développeur sur un autre continent, avec spécifications différentes à chaque niveau suivant les consignes/niveau/langue/priorités/besoins/limites/obsessions/normes de chaque strate ; alors que le premier besoin exprimée par l’utilisateur pourrait souvent (pas toujours, loin de là !) suffire au développeur final pour travailler, sans rajouter un effet téléphone arabe et une lourdeur monstrueuse en gestion et « pilotage ».</p>
<div class="footnotes"><h4 class="footnotes-title">Notes</h4>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/10/14/246-des-millions-de-lignes-a-travers-le-millefeuille#rev-pnote-217-1" id="pnote-217-1">1</a>] <em>Je dis toujours que SAP est totalitaire car il veut </em>tout<em> contrôler.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/10/14/246-des-millions-de-lignes-a-travers-le-millefeuille#rev-pnote-217-2" id="pnote-217-2">2</a>] <em>Ce qui devient vite illisible à mon avis.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/10/14/246-des-millions-de-lignes-a-travers-le-millefeuille#rev-pnote-217-3" id="pnote-217-3">3</a>] <em>Si vous ne comprenez pas immédiatement la fonction des tables et colonnes par leur nom, c’est tout à fait <del>normal</del> habituel sur SAP.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/10/14/246-des-millions-de-lignes-a-travers-le-millefeuille#rev-pnote-217-4" id="pnote-217-4">4</a>] <em>Au passage, je suis surpris du faible nombre d’index présents sur les tables de SAP par rapport à celles du concurrent Oracle Applications.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/10/14/246-des-millions-de-lignes-a-travers-le-millefeuille#rev-pnote-217-5" id="pnote-217-5">5</a>] <em>Le mandant est une clé implicite de chaque table. Il correspond à une « vision du monde » et permet de séparer plusieurs jeux de données (test, paramétrage...) voire certains programmes.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/10/14/246-des-millions-de-lignes-a-travers-le-millefeuille#rev-pnote-217-6" id="pnote-217-6">6</a>] <em>N’exagérons pas, c’est « juste » du décisionnel, ni la production ni la logistique n’ont été affectées.</em></p></div>
https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/10/14/246-des-millions-de-lignes-a-travers-le-millefeuille#comment-formhttps://www.coindeweb.net/blogsanssujetprecis/index.php?feed/atom/comments/217Prise de tête en ABAPurn:md5:f11bca39aa015f90a708f8efb799ac3f2006-07-19T13:31:00+00:002010-11-01T18:13:08+00:00ChristopheInformatique lourdebase de donnéesdommagedysfonctionnementdéveloppementergonomieERPhaineincohérenceinformatiqueoffshoreponctuationprise de têteSAPSSII<p>Aberrations syntaxiques d’un langage aux lacunes parfois hallucinantes.</p> <p><em>(Rappel : L’ABAP est le langage dans lequel tout SAP R/3 est développé. On parle là d’un <a href="https://www.coindeweb.net/blogeclectique/index.php?category/Informatique-lourder">ERP</a> à beaucoup de millions d’euros de license, avec une industrie entière qui gravite autour. Il montre parfois qu’il a trois décennies d’âge.)</em></p>
<p>Ce code compile (sans rien faire mais ce n’est pas le problème) :</p>
<blockquote><p><code>REPORT ZCCO_TEST.</code><br />
<code>IF 1 > 2 .</code><br />
<code>ENDIF.</code></p></blockquote>
<p>Ceci ne compile pas :</p>
<blockquote><p><code>REPORT ZCCO_TEST.</code><br /><code>IF ( 1 * 5 ) > 2 .</code><br /><code>ENDIF.</code></p></blockquote>
<p>“<code>Relational operator "*" is not supported</code>”, qu’il dit. On ne fait donc pas de calcul dans une condition. Je suis condamné à utiliser une variable de travail (une de plus).</p>
<p>Ceci non plus ne passe pas :</p>
<blockquote><p><code>REPORT ZCCO_TEST.<br />IF 1>2.<br />ENDIF.</code></p></blockquote>
<p>Pourquoi ? Il manque des espaces autour du <code>></code>. Un scandale, effectivement.</p>
<p>C’est pareil pour les parenthèses (<code>IF ( 1 > 2 ) .</code>), il faut les séparer de ce qu’elles contiennent par des espaces. Sauf dans le cas d’un ordre SQL comme <code>SELECT... INTO (variable1, variable2) WHERE...</code> où, là, les parenthèses doivent être collées au reste.</p>
<p>Les limites de ce genre sont pléthore en ABAP. Je hais ce langage. On peut faire son boulot avec, mais c’est comme taper sur un clavier avec des moufles.</p>
<p>Il y a aussi des incohérences un peu pénibles. Par exemple, deux syntaxes totalement différentes selon que l’on recherche une donnée dans une table réelle (de la base de données) ou interne (un bête tableau en mémoire, de même structure que la table réelle).</p>
<p>Le premier ressemble à ça (recherche d’un poste de commande sur sa clé primaire constituée de <code>vbeln</code> et <code>posnr</code>) :</p>
<blockquote><p><code>SELECT ... FROM vbap<br />WHERE vbeln = ... <br />AND posnr = ...</code></p></blockquote>
<p>Par contre pour la table interne :</p>
<blockquote><p><code>READ TABLE t_vbap ... <br />WITH KEY vbeln =...<br />posnr = ...</code></p></blockquote>
<p>Vous avez remarqué : dans un cas il y a un <code>AND</code> entre les deux critères de recherche. Dans l’autre, non. Pourquoi ? Mystère. Petit détail, oui. Mais à la fin de la journée on en perd, des minutes à faire plaisir au compilateur.</p>https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/07/19/186-prise-de-tete-en-abap#comment-formhttps://www.coindeweb.net/blogsanssujetprecis/index.php?feed/atom/comments/167La Guerre des ERP : SAP vs Oracle Applications (5) : Schémas de donnéesurn:md5:bbf126b980bb6984d074230ba27103bb2006-07-05T11:11:00+00:002010-11-01T08:26:48+00:00ChristopheInformatique lourdebase de donnéescomplexitédommagedéveloppementergonomieERPincohérenceinformatiquemétainformationOracleprise de têteSAPSQLtravail<p>Un ERP, c’est une foule d’écrans, de fonctions, de formulaires... pour manier des données, mais d’abord une masse (souvent montrueuse) de données soigneusement rangées dans des tables, bien au chaud au sein d’une grosse base.</p>
<p>Ce qui ne veut pas dire que les deux ennemis se ressemblent sur ce point...</p> <p>(<em>Caveat</em> : Des notions de maniement de bases de données ne nuiront pas à la compréhension de ce qui suit. - <strong>Addendum</strong> : <a href="https://www.coindeweb.net/blogeclectique/index.php?post/2008/05/28/403-cle-primaire-de-substitution-ou-cle-naturelle">Je parle plus en détail et en théorie des différences entre clés fonctionnelles et arbitraires dans ce billet</a>)</p>
<h3>Oracle Applications</h3>
<p>Le schéma de données est à peu près <a href="http://tecfa.unige.ch/staf/staf-h/tassini/staf2x/Heidi/last_bd.htm">normalisé</a> ; les noms de table sont en anglais, à peu près explicites. Chaque ligne porte un identifiant numérique, distinct de celui vu par l’être humain sur un écran ou un rapport. Bref, une conception comme on l’enseigne aux étudiants de première année d’informatique.</p>
<p>Par exemple, la table des en-têtes de commande <code>OE_ORDER_HEADERS</code> a comme
<a href="http://fr.wikipedia.org/wiki/Clé_primaire">clé primaire</a> un identifiant numérique <code>ORDER_HEADER_ID</code>, et un numéro de commande utilisateur <code>ORDER_NUMBER</code>. <br />Cet <code>ORDER_HEADER_ID</code> sert de clé externe pour une <a href="http://fr.wikipedia.org/wiki/Jointure">jointure</a> sur la table des lignes de commandes, <code>OE_ORDER_LINES</code>, dont la clé est <code>ORDER_LINE_ID</code>. <br />Pour être compréhensible par un humain, une ligne (un enregistrement dans la table), possède les champs <code>LINE_NUMBER</code> (valeur démarrant à <code>1</code>) et <code>SHIPMENT_NUMBER</code> (idem). <br />Ce sont ces deux dernières valeurs qui s’affichent sur un écran ou un rapport, les clés réelles ne sont utiles qu’aux développeurs.</p>
<p><em>Exemple</em> : par le <code>ORDER_HEADER_ID</code> <code>175321</code>, je peux joindre les deux tables
et récupérer les identifiants apparents de la commande, par exemple <code>ORDER_NUMBER</code> = <code>1000</code>
et <code>LINE_NUMBER</code> = <code>1</code> et <code>SHIPMENT_NUMBER</code> = <code>1</code>.</p>
<p>Un <code>ORDER_NUMBER</code> possède ses contraintes de numérotation (telle plage pour tel type de <em>business</em> par exemple) mais l’<code>ORDER_HEADER_ID</code>, identifiant unique de l’enregistrement, est unique et peut valoir ce qu’il veut. En général c’est une valeur abstraite mais « compréhensible » par un humain, genre <code>175321</code>. Idem pour l’<code>ORDER_LINE_ID</code>, par exemple <code>321000</code>.</p>
<p>À première vue, <strong>doublonner les identifiants numériques et les identifiants visibles semble inutile</strong> et ne facilite pas le travail du développeur ; mais au contraire cela offre une souplesse complète, les identifiants numériques pouvant
être manipulés à volonté sans conséquence visible pour l’utilisateur<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/07/05/175-la-guerre-des-erp-sap-vs-oracle-applications-5-schemas-de-donnees#pnote-158-1" id="rev-pnote-158-1">1</a>]</sup>. De plus, chacune des tables principales n’a ainsi qu’une seule colonne en clé primaire, ce qui simplifie bien des choses<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/07/05/175-la-guerre-des-erp-sap-vs-oracle-applications-5-schemas-de-donnees#pnote-158-2" id="rev-pnote-158-2">2</a>]</sup>.</p>
<p>Petit bonus également pour le développeur : avec un peu d’habitude d’une base précise, il sait qu’un <code>ORDER_HEADER_ID</code> tourne autour de <code>170-180000</code>, un <code>ORDER_LINE_ID</code> de <code>320000</code>, et les reconnaît au premier coup d’oeil.<br />De la même manière, il sait vite que la colonne <code>ORDER_TYPE_ID</code> des en-têtes de commande pointe vers <code>OE_ORDER_TYPES</code>, et que la valeur <code>74</code> correspond par exemple au type de commande « Petit électroménager » dans telle installation de tel revendeur d’électroménager.<br />Le seul inconvénient que je connaisse est que la mise en place sur différentes bases du même paramétrage (par exemple création d’un nouveau type de commande sur les bases de développement, recette et production) mène à des différences d’identifiants numériques (sauf coup de bol). Ce n’est pas censé être un problème si on programme proprement (ne jamais mettre ces identifiants « en dur » dans un programme), et si on rafraîchit suffisamment souvent ses bases de développement et recette<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/07/05/175-la-guerre-des-erp-sap-vs-oracle-applications-5-schemas-de-donnees#pnote-158-3" id="rev-pnote-158-3">3</a>]</sup>.</p>
<p>Donc au final un schéma très propre, forcément touffu vu le nombre de tables impliquées, qui a cependant la mauvaise habitude de devenir de plus en plus tordu avec le temps et les nouvelles fonctionnalités. La pire aberration que j’ai rencontrée provient de lots de données qui migrent de table en table suivant l’état du statut au sein du flux logistique. Il y a peut-être une raison profonde mais cela jure avec la cohérence du reste.</p>
<h3>SAP R/3</h3>
<p>Le modèle de données de R/3 est à la fois plus simple et plus cauchemardesque.</p>
<p>Comme dit dans <a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/03/04/87-les-joies-de-l-erp-et-du-crm-i">un précédent billet</a>, R/3 (l’ERP « classique ») utilise surtout des tables dont les noms inspirés de l’allemand ont quatre lettres, du genre <code>MARA</code>, <code>VBAK</code>, <code>LIKP</code>, <code>T001</code>...</p>
<p>Dans ces tables il n’y a pas d’identifiant numérique comme sous Oracle. <strong>La clé primaire est fonctionnelle</strong>. Pour <code>VBAK</code> (les en-têtes de commande), cette clé est composée des champs <code>MANDT</code> (le mandant, qui en quelque sorte identifie la base de travail<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/07/05/175-la-guerre-des-erp-sap-vs-oracle-applications-5-schemas-de-donnees#pnote-158-4" id="rev-pnote-158-4">4</a>]</sup>) et de <code>VBELN</code>, le document commercial <em>visible par l’utilisateur</em> !</p>
<p>Évidemment, dans <code>VBAP</code>, correspondant aux postes (lignes de commandes), ce même <code>VBELN</code> sera répercuté pour identifier ce qui correspond à une commande donnée. Et la clé primaire de cette table des postes est un triplet <code>MANDT</code>, <code>VBELN</code>, <code>POSNR</code>.<br />De même, la table <code>TVAK</code> des types de commande contient la valeur de type directement
dans sa clé.</p>
<p>En conséquence, <strong>renommer un objet sous SAP revient à renommer sa clé primaire</strong> ! Ça ne se fait pas à la légère, sous peine de corrompre les données. Donc, sous SAP, on ne <strong>modifie jamais rien directement dans les tables</strong><sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/07/05/175-la-guerre-des-erp-sap-vs-oracle-applications-5-schemas-de-donnees#pnote-158-5" id="rev-pnote-158-5">5</a>]</sup> ! Le système fait d’ailleurs de son mieux pour l’interdire au développeur, et il faut utiliser les fonctions, BAPIs, BADIs, IDOCs, <em>user exits</em>, programmes d’import... livrés avec le système.</p>
<p>Pire : la clé « fonctionnelle » utilisée ici n’est <strong>plus un moyen de vérifer l’unicité ou la destruction d’un enregistrement</strong>. Supposons une ligne de commande (clé : <code>VBELN</code>+<code>POSNR</code>) créée, puis détruite (pas logiquement, mais physiquement et totalement), puis récréée avec le même numéro de poste (ligne)<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/07/05/175-la-guerre-des-erp-sap-vs-oracle-applications-5-schemas-de-donnees#pnote-158-6" id="rev-pnote-158-6">6</a>]</sup>. Un programme extérieur<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/07/05/175-la-guerre-des-erp-sap-vs-oracle-applications-5-schemas-de-donnees#pnote-158-7" id="rev-pnote-158-7">7</a>]</sup> ne peut savoir si une ligne qu’il a mémorisée (par sa clé <code>VBELN</code>+<code>POSNR</code>) est la même ou pas.<br />Sous Oracle, le <code>ORDER_LINE_ID</code> aurait totalement disparu, et un nouveau aurait été recréé, même si l’utilisateur a choisi de conserver les mêmes <code>LINE_NUMBER</code> et <code>SHIPMENT_NUMBER</code>.</p>
<p>Il y a plus vicieux. L’utilisateur verra à l’écran un document de vente numéroté <code>18500</code>, alors que la base stockera en réalité dans <code>VBELN</code> la chaîne <code>0000018500</code> (dix caractères). Forcer la taille de la chaîne a un intérêt en terme de classement (sans cela, <code>1869</code> serait entre <code>18500</code> et <code>18695</code>), mais pour le développeur c’est un petit cauchemar : chaque variable est susceptible de contenir la chaîne avec ou sans ses zéros initiaux et il faut convertir à gogo (sachant que le moindre appel de fonction en ABAP fait cinq lignes et qu’elles ne peuvent pas être imbriquées les unes dans les autres sur la même ligne comme dans la plupart des langages de programmation).</p>
<p>Encore plus drôle : les nouveaux modules, en premier lieu le CRM mais aussi des morceaux de R/3, ont décidé de prendre en compte les avancées du dernier quart du siècle dernier en matière de bases de données, et de passer aux identifiants numériques !<br />Mais dans une optique d’universalité (sans doute pour faciliter la fusion de bases SAP différentes), ces identifiants sont des <strong>GUID</strong> (<em>global identifier</em>), en hexadécimal, du genre de 447072A2FB800063000000000A1F352F. <br />Allez déboguer des programmes où la moitié des variables sont des identifiants de ce genre...<br />Le plus drôle c’est que ces GUID apparaissent parfois à l’utilisateur (abomination peut-être liée au paramétrage là où je travaille).</p>
<p>Enfin, pour compliquer la tâche, SAP interdisant tout accès à Oracle (la base, qui en général tourne derrière) et imposant ses propres outils de développement, une bonne partie des outils de contrôle d’Oracle sont inaccessibles. Adieu les bonnes grosses requêtes de contrôle du bon déroulement d’un programme qui impliquaient dix tables...<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/07/05/175-la-guerre-des-erp-sap-vs-oracle-applications-5-schemas-de-donnees#pnote-158-8" id="rev-pnote-158-8">8</a>]</sup></p>
<h3>Verdict</h3>
<p>Travailler avec Oracle avait ses bons côtés ; j’ai beaucoup de mal à apprécier SAP pour le développement. Autant SAP est en avance par son interface perfectible mais fonctionnelle, et l’effroyable panel de possibilités, autant Oracle permet au développeur de faire ce qu’il veut pour intervenir sur les données ou rajouter des programmes, sans lui mettre de bâtons dans les roues. Mais on demande rarement son avis au développeur lors du choix d’un ERP...</p>
<p><a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/06/28/156-la-guerre-des-erp-sap-vs-oracle-applications-1-des-interfaces-hideuses">Partie 1 : Des interfaces hideuses</a></p>
<p><a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/06/30/177-la-guerre-des-erp-sap-vs-oracle-applications-2-deux-gros-patchworks">Partie 2 : Deux gros patchworks</a></p>
<p><a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/07/03/178-la-guerre-des-erp-sap-vs-oracle-applications-3-des-interfaces-tres-particulieres">Partie 3 : Des interfaces très particulières</a></p>
<p><a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/07/04/176-la-guerre-des-erp-sap-vs-oracle-applications-4-philosophie-opposees">Partie 4 : Philosophies opposées</a></p>
<p>Partie 5 : Schémas de données</p>
<div class="footnotes"><h4>Notes</h4>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/07/05/175-la-guerre-des-erp-sap-vs-oracle-applications-5-schemas-de-donnees#rev-pnote-158-1" id="pnote-158-1">1</a>] <em>Encore un niveau en dessous, Oracle identifie l’enregistrement sur le disque dur par un autre identifiant, le <code>ROWID</code>, qui suit le même principe, et est susceptible de modification à tout moment, en cas de réorganisation des données. L’utilisateur de la base de donneés (le développeur) n’a en général pas à se préoccuper de ce <code>ROWID</code>.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/07/05/175-la-guerre-des-erp-sap-vs-oracle-applications-5-schemas-de-donnees#rev-pnote-158-2" id="pnote-158-2">2</a>] <em>Les tables de correspondance notamment peuvent avoir des clés composées, et rien n’interdit de rajouter des index à volonté sur les autres colonnes (au contraire).</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/07/05/175-la-guerre-des-erp-sap-vs-oracle-applications-5-schemas-de-donnees#rev-pnote-158-3" id="pnote-158-3">3</a>] <em>Et là on s’aperçoit que c’est une opération lourde ; je travaille actuellement avec une base de développement vieille d’un an au bas mot, et mon client précédent attendait souvent six mois pour rafraîchir son Oracle.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/07/05/175-la-guerre-des-erp-sap-vs-oracle-applications-5-schemas-de-donnees#rev-pnote-158-4" id="pnote-158-4">4</a>] <em>Je simplifie. Un mandant indique une </em>vision du monde<em>, et on peut ainsi collectioner les mandants dans une même base de données SAP : mandant de paramétrage, mandant de développement ne comportant que des programmes, mandant de test comportant des données. Lourd mais pratique. Chaque clé primaire de table commence par le mandant.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/07/05/175-la-guerre-des-erp-sap-vs-oracle-applications-5-schemas-de-donnees#rev-pnote-158-5" id="pnote-158-5">5</a>] <em>Exception pour les tables ajoutées par l’utilisateur que SAP à proprement parler ignore.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/07/05/175-la-guerre-des-erp-sap-vs-oracle-applications-5-schemas-de-donnees#rev-pnote-158-6" id="pnote-158-6">6</a>] <em>Je suis d’accord que ça ne devrait pas pouvoir se faire, mais l’utilisateur peut le faire, et il le fera.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/07/05/175-la-guerre-des-erp-sap-vs-oracle-applications-5-schemas-de-donnees#rev-pnote-158-7" id="pnote-158-7">7</a>] <em>Comme celui que je suis en train d’écrire au moment où je rédige ceci.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/07/05/175-la-guerre-des-erp-sap-vs-oracle-applications-5-schemas-de-donnees#rev-pnote-158-8" id="pnote-158-8">8</a>] <em>De plus se pose le problème des droits d’accès à la base, forcément restreints dans ce contexte...</em></p></div>
https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/07/05/175-la-guerre-des-erp-sap-vs-oracle-applications-5-schemas-de-donnees#comment-formhttps://www.coindeweb.net/blogsanssujetprecis/index.php?feed/atom/comments/158La Guerre des ERP : SAP vs Oracle Applications (4) : Philosophie opposéesurn:md5:4d36d1d9d4ea7ec1063602c848f554ee2006-07-04T12:49:00+00:002010-10-31T21:19:42+00:00ChristopheInformatique lourdeabominationanalogiebase de donnéescomplexitédommagedéveloppementergonomieERPincohérenceinformatiqueMacOracleorganisationpanurgismeprise de têteSAPSQLsécuritétravailéconomieévolution<p>« SAP conçoit un Mac, Oracle assemble un PC » : de l’ABAP et du PL/SQL, et des serveurs.</p> <h3>Philosophie</h3>
<p>La différence de philosophie entre SAP et Oracle Applications est très bien résumée par <a href="http://blog1.lemondeinformatique.fr/ingenierie_logicielle/2006/05/sap_construit_u.html">cette remarque de Ray Wang, reprise par Olivier Rafal</a> : <strong>SAP conçoit un Mac, Oracle assemble un PC</strong>.<br />
Autrement dit : SAP veut tout faire de A à Z (interfaces, base, administration...) et verrouille ses interfaces, alors qu’Oracle procède plutôt par agrégat de briques interconnectées, disponibles seules, dont l’utilisateur peut faire un peu ce qu’il veut.</p>
<h3>La base</h3>
<p>Oracle vend des bases de données avant tout, il a donc bâti son ERP autour de cette base, en exploitant ses spécificités (l’ERP a cependant toujours une génération de retard sur la base et les outils annexes, par conservatisme et par nécessité de migrer et certifier une telle masse de code).<br />Les tables sont directement accessibles depuis le code source du programme en PL/SQL.</p>
<p>SAP considère que la base de données peut être n’importe quoi : Oracle, SQL Server, DB2, <del>MySQL</del>... <del>Oui, même MySQL (qui existe sous la forme de <a href="http://www.mysql.com/products/maxdb/" hreflang="en">MaxDB</a> dans le monde SAP)</del> (<strong>Correction</strong> : <em>En fait, MaxDB n’a rien à voir avec la base MySQL. Ça semblait gros quand même...)</em>. SAP rajoute donc sa couche d’administration de la base, impose de passer par une version maison appauvrie du SQL pour interroger la base, et interdit toute modification sous-jacente au niveau SQL.<br />Ironie de l’histoire : l’essentiel des installations de SAP tourne cependant sous Oracle (par sécurité et panurgisme), et rapportent donc de l’argent au concurrent principal...</p>
<h3>Langage : SAP et l’ABAP</h3>
<p>SAP est basé sur un langage spécifique, utilisé nulle part ailleurs, qui fleure bon le néolithique de l’informatique, à savoir l’<strong>ABAP</strong>. Il paraît que cela ressemble au Cobol avec quelques notions simplettes de SQL.</p>
<p>Il est basé sur les notions de « structure » (un enregistrement de base de données en fait, par exemple <em>une</em> ligne de commande), que l’on manipule dans des <em>tables internes</em>, et que l’on synchronise à l’occasion avec les vraies tables de la base de données. Les jointures sont lourdes, et récupérer des données consiste souvent à récupérer un jeu de lignes, le parcourir, et réeffectuer des requêtes pour chaque ligne.</p>
<p>Le langage a tout ce qu’il faut pour être qualifié de langage de programmation, mais il manque beaucoup de « sucre syntaxique » apparu depuis les années 1990. Comme je l’ai déjà évoqué, l’environnement de développement est un éditeur imposé, intégré, basique et sans fioriture qui connaît à peine la coloration syntaxique des commentaires. Programmer en ABAP me fait l’effet de programmer avec un boulet aux pieds.</p>
<h3>Langage : Oracle et PL/SQL</h3>
<p>Oracle Applications (l’ERP) est basé sur le <strong>PL/SQL</strong>, le langage intégré à Oracle (la base). On peut aussi utiliser du Java, mais ce n’est pas si courant, du moins sur les modules les moins récents.</p>
<p>Le PL/SQL a l’avantage d’être un véritable langage, sans doute pas aussi souple et riche que du .Net ou du Ruby, mais plutôt un mariage heureux entre le Pascal et le SQL, qui évolue peu à peu et, je pense, dans la bonne direction, sans trop de fioritures inutiles. Un avantage majeur est que l’on interagit directement avec les données sans couche intermédiaire qui freine ou impose ses limites ; on profite de <em>toutes</em> les fonctionnalités d’Oracle (la base)<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/07/04/176-la-guerre-des-erp-sap-vs-oracle-applications-4-philosophie-opposees#pnote-141-1" id="rev-pnote-141-1">1</a>]</sup>. Les « tables internes » ne servent que dans certains cas précis d’optimisation (mise à jour en masse), puisque la base optimise déjà le commun des requêtes toute seule. La création de « requêtes de feu » de plusieurs pages n’est pas un problème ; le principe est de sous-traiter au maximum à la base de données puisqu’on est très proche d’elle.</p>
<p>Le PL/SQL est conçu pour manipuler des données mais est assez « généraliste », pas réduit à ne travailler qu’avec l’ERP. Exécuter du code d’un autre langage (hors de la base cependant, donc au niveau du système d’exploitation) n’est pas un problème, c’est prévu.</p>
<h3>Serveurs d’application et autres monstres</h3>
<p>Oracle Application inclut un serveur d’application maison, genre d’objet que je connais très mal par ailleurs. SAP mitonne son équivalent, <a href="http://de.wikipedia.org/wiki/SAP_NetWeaver" hreflang="de">Netweaver</a>, mais je ne connais pas d’environnement où Netweaver soit utilisé indépendamment de SAP.</p>
<p>À côté de tout ça, chacun a son essaim d’outils annexes, modules optionnels, portails webs, etc.</p>
<h3>Sous le capot</h3>
<p>Le modèle de données n’a <em>rien</em> à voir, et de ceci que je vais parler <a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/07/05/175-la-guerre-des-erp-sap-vs-oracle-applications-5-schemas-de-donnees">la prochaine fois</a>…</p>
<p><a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/06/28/156-la-guerre-des-erp-sap-vs-oracle-applications-1-des-interfaces-hideuses">Partie 1 : Des interfaces hideuses</a></p>
<p><a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/06/30/177-la-guerre-des-erp-sap-vs-oracle-applications-2-deux-gros-patchworks">Partie 2 : Deux gros patchworks</a></p>
<p><a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/07/03/178-la-guerre-des-erp-sap-vs-oracle-applications-3-des-interfaces-tres-particulieres">Partie 3 : Des interfaces très particulières</a></p>
<p>Partie 4 : Philosophies opposées</p>
<p><a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/07/05/175-la-guerre-des-erp-sap-vs-oracle-applications-5-schemas-de-donnees">Partie 5 : Schémas de données</a></p>
<div class="footnotes"><h4>Notes</h4>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/07/04/176-la-guerre-des-erp-sap-vs-oracle-applications-4-philosophie-opposees#rev-pnote-141-1" id="pnote-141-1">1</a>] <em>Et vu le prix de la licence, c’est bien la moindre des choses...</em></p></div>
https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/07/04/176-la-guerre-des-erp-sap-vs-oracle-applications-4-philosophie-opposees#comment-formhttps://www.coindeweb.net/blogsanssujetprecis/index.php?feed/atom/comments/141La Guerre des ERP : SAP vs Oracle Applications (3) : Des interfaces très particulièresurn:md5:ffb69bfbd90f13d2583d6312218235a42006-07-03T10:50:00+00:002010-10-31T21:15:53+00:00ChristopheInformatique lourdeanalogieargentbase de donnéescomplexitédommagedysfonctionnementergonomieERPincohérenceinformatiqueOracleorganisationprise de têteSAPSSIItravailéconomieévolution<p>Caractéristiques historiques et techniques des interfaces de SAP et Oracle.</p> <p>Les deux produits se basent au final sur des <strong>interfaces (apparence et technique) totalement propriétaires et utilisées nulle part ailleurs</strong> (sinon par leurs autres produits).</p>
<p>Qu’on ne s’imagine pas que cette indépendance permet de s’affranchir du système d’exploitation sous-jacent, je n’ai jamais vu en pratique tourner ces produits ailleurs que sous Windows. Je me trompe peut-être, les deux interfaces ont migré au moins partiellement vers Java, avec la persective théorique d’être utilisable n’importe où, mais SAP notamment est connu pour être très proche de Microsoft. Le projet <a href="http://www.lemondeinformatique.fr/actualites/lire-sapphire-06-paris-muse-devra-rendre-l-utilisateur-heureux-19651.html">Duet</a> est d’ailleurs destiné à lier de plus en plus SAP et Office. L’évolution sous forme d’applis web pourrait rendre le problème caduc, au moins pour certains modules, ou certains écrans.</p>
<p>La cause de ces interfaces bizarres serait plutôt qu’<strong>à force de migrer de système en système</strong> au cours de l’histoire de l’informatique (du listing papier de 1972 au terminal texte de 1985 au client-serveur de 1990 au client lourd de 2000 au futur <em>full web</em> de 200?), avec l’impératif de maintenir le maximum de compatibilité (pour limiter des coûts de migration toujours astronomiques<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/07/03/178-la-guerre-des-erp-sap-vs-oracle-applications-3-des-interfaces-tres-particulieres#pnote-160-1" id="rev-pnote-160-1">1</a>]</sup>), chacun des deux systèmes s’est « enfermé » dans son propre univers. Le souci de l’interfaçage avec le reste des outils professionnels (notamment Office) s’accroît avec le temps, mais on ne cherche pas des applications intégrées parfaitement au système d’exploitation en apparence comme en comportement.</p>
<p>De plus, SAP et Oracle Applications se <strong>vendent sur leurs fonctionnalités</strong> (et leur capacité à faire le maximum de choses avec le minimum de monde, du moins en théorie), pas sur leur ergonomie ou leur <em>design</em> (un commercial m’a confié présenter Oracle Applications sur un écran au client le plus tard possible).</p>
<p>On obtient donc l’inverse total et simultané des philosophies à la Microsoft (en mettre plein la vue et insister sur la facilité d’utilisation apparente), à la Apple (interface nette et cohérente avant tout), ou à la Unix (austère et élitiste mais propre).</p>
<p><a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/06/28/156-la-guerre-des-erp-sap-vs-oracle-applications-1-des-interfaces-hideuses">Partie 1 : Des interfaces hideuses</a></p>
<p><a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/06/30/177-la-guerre-des-erp-sap-vs-oracle-applications-2-deux-gros-patchworks">Partie 2 : Deux gros patchworks</a></p>
<p>Partie 3 : Des interfaces très particulières</p>
<p><a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/07/04/176-la-guerre-des-erp-sap-vs-oracle-applications-4-philosophie-opposees">Partie 4 : Philosophies opposées</a></p>
<p><a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/07/05/175-la-guerre-des-erp-sap-vs-oracle-applications-5-schemas-de-donnees">Partie 5 : Schémas de données</a></p>
<div class="footnotes"><h4>Notes</h4>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/07/03/178-la-guerre-des-erp-sap-vs-oracle-applications-3-des-interfaces-tres-particulieres#rev-pnote-160-1" id="pnote-160-1">1</a>] <em>En réécriture ou adaptation de programmes spécifiques au client, revalidation de tous les flux métier, découverte de nouveaux bugs, formation, temps de migration technique des données, nouvelles normes de programmation... Une migration de version de SAP ou Oracle prend facilement plusieurs mois.</em></p></div>
https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/07/03/178-la-guerre-des-erp-sap-vs-oracle-applications-3-des-interfaces-tres-particulieres#comment-formhttps://www.coindeweb.net/blogsanssujetprecis/index.php?feed/atom/comments/160La Guerre des ERP : SAP vs Oracle Applications (2) : Deux gros patchworksurn:md5:25367ff598fa2f1cbcc9880db3e1df822006-06-30T13:42:00+00:002010-10-31T21:13:59+00:00ChristopheInformatique lourdeargentbase de donnéescomplexitéCRMdommagedéveloppementergonomieERPincohérenceinformatiqueorganisationprise de têteSSIItravailéconomieévolution<p>Les deux logiciels sont en réalité un assemblage de plusieurs modules développés à part...</p> <p>Les deux logiciels sont en réalité un <strong>assemblage de plusieurs modules développés à part</strong> les uns des autres, parfois pour des commandes précises de client, parfois rachetés à d’autres entreprises, reliés à grand-peine et intégrés au chausse-pied.</p>
<p>Les <strong>modules financiers</strong> sont les plus anciens<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/06/30/177-la-guerre-des-erp-sap-vs-oracle-applications-2-deux-gros-patchworks#pnote-159-1" id="rev-pnote-159-1">1</a>]</sup>, et vus leur complexité et leur importance<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/06/30/177-la-guerre-des-erp-sap-vs-oracle-applications-2-deux-gros-patchworks#pnote-159-2" id="rev-pnote-159-2">2</a>]</sup>, ils n’ont jamais été totalement réécrits. <br />Du point de vue de l’organisation des données, ils ont le mérite d’une architecture simple et compréhensible. À l’utilisation, ils me sont à peu près incompréhensibles (mais je ne suis ni comptable ni formé sur ces modules).</p>
<p>À l’inverse les modules de <a href="http://fr.wikipedia.org/wiki/Gestion_de_la_relation_client">CRM</a><sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/06/30/177-la-guerre-des-erp-sap-vs-oracle-applications-2-deux-gros-patchworks#pnote-159-3" id="rev-pnote-159-3">3</a>]</sup>, à la mode depuis quelques années, bénéficient de tous les derniers gadgets d’interface <em>ad nauseam</em> : arborescences, tableaux intégrés genre Excel et pléthore d’onglets, sous-onglets, sous-sous-onglets, fenêtres imbriquées, paramétrage plus-flexible-tu-meurs.... <br />En général ces innovations sont contrebalancées par la perte des avantages de l’interface « ancien style » (facilité de recherche des champs techniques, copier-coller facile, double-clic dans SAP...) et un degré de complexité de plus dans la programmation<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/06/30/177-la-guerre-des-erp-sap-vs-oracle-applications-2-deux-gros-patchworks#pnote-159-4" id="rev-pnote-159-4">4</a>]</sup>.</p>
<p>Oracle ayant racheté plusieurs de ses challengers (l’ERP <a href="http://en.wikipedia.org/wiki/Peoplesoft" hreflang="en">Peoplesoft, lui-même acquéreur auparavant de JDEdwards</a>, ou le CRM <a href="http://en.wikipedia.org/wiki/Siebel_Systems" hreflang="en">Siebel</a>), les incohérences de logique et d’interface ne sont pas terminées dans l’unification de tout ce beau monde (projet <a href="http://en.wikipedia.org/wiki/Fusion_Software" hreflang="en">Fusion</a> d’Oracle). Ce qui était au départ une base de données qui faisait tourner des programmes PL/SQL se dirige vers un mille-feuilles de PL/Java/<a href="http://fr.wikipedia.org/wiki/XML">XML</a>/<a href="http://fr.wikipedia.org/wiki/Service_Oriented_Architecture">SOA</a>/<a href="http://en.wikipedia.org/wiki/BPEL" hreflang="en">BPEL</a> intégrant l’ancienne suite d’Oracle, celle de Peoplesoft, etc.<br />SAP pour sa part cherche plus à tout redévelopper lui-même, mais fait évoluer son produit radicalement. R/3 (l’ERP « classique ») a peu évolué pendant que la partie CRM évoluait à fond, la différence est flagrante.</p>
<p><a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/06/28/156-la-guerre-des-erp-sap-vs-oracle-applications-1-des-interfaces-hideuses">Partie 1 : Des interfaces hideuses</a></p>
<p>Partie 2 : Deux gros patchworks</p>
<p><a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/07/03/178-la-guerre-des-erp-sap-vs-oracle-applications-3-des-interfaces-tres-particulieres">Partie 3 : Des interfaces très particulières</a></p>
<p><a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/07/04/176-la-guerre-des-erp-sap-vs-oracle-applications-4-philosophie-opposees">Partie 4 : Philosophies opposées</a></p>
<p><a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/07/05/175-la-guerre-des-erp-sap-vs-oracle-applications-5-schemas-de-donnees">Partie 5 : Schémas de données</a></p>
<div class="footnotes"><h4>Notes</h4>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/06/30/177-la-guerre-des-erp-sap-vs-oracle-applications-2-deux-gros-patchworks#rev-pnote-159-1" id="pnote-159-1">1</a>] <em>Rappelez-vous : ce sont les comptables qui ont payé le développement de l’informatique (avec les militaires).</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/06/30/177-la-guerre-des-erp-sap-vs-oracle-applications-2-deux-gros-patchworks#rev-pnote-159-2" id="pnote-159-2">2</a>] <em>Un bon consultant dirait « criticité ».</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/06/30/177-la-guerre-des-erp-sap-vs-oracle-applications-2-deux-gros-patchworks#rev-pnote-159-3" id="pnote-159-3">3</a>] <em>Gestion de la Relation Client, en pseudo-français ; rappelons que cela couvre aussi bien la télé- que l’après-vente.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/06/30/177-la-guerre-des-erp-sap-vs-oracle-applications-2-deux-gros-patchworks#rev-pnote-159-4" id="pnote-159-4">4</a>] <em>Sous SAP : La programmation à l’ancienne genre ABAP/Cobol avait le mérite de la clarté besogneuse. Tenter d’y rajouter des notions de programmation objet relève du mariage contre-nature, et la difficulté tient autant à l’environnement de développement lourdingue qu’à l’évolution du langage. Sous Oracle, la transition me semble plus facile, peut-être parce qu’on reste finalement au sein de triggers, programmes, packages PL/SQL en rajoutant juste quelques types d’objets différents ; je n’ai pas touché au Java.</em></p></div>
https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/06/30/177-la-guerre-des-erp-sap-vs-oracle-applications-2-deux-gros-patchworks#comment-formhttps://www.coindeweb.net/blogsanssujetprecis/index.php?feed/atom/comments/159La Guerre des ERP : SAP vs Oracle Applications (1) : Des interfaces hideusesurn:md5:eec056667d95c5a35b8de23a72af68d02006-06-28T12:58:00+00:002010-10-31T18:25:46+00:00ChristopheInformatique lourdeabominationargentbase de donnéescomplexitéCRMdommagedéfense du françaisergonomieERPexpertiseincohérenceinformatiqueOracleorganisationprise de têteSAPSSIItravailéconomie<p>Les deux poids lourds mondiaux des logiciels de gestion d’entreprise intégrés partagent les caractéristiques communes de lourdeur certaine et d’une ergonomie plus que perfectible.</p> <p>Les deux leaders sur le marché de l’ERP sont <strong>SAP</strong>, n°1 incontesté <em>made in Germany</em>, lourd et ruineux, et l’américain <strong>Oracle Applications</strong>, un cran en-dessous en terme de marché, chiffre d’affaire et fonctionnalités, mais qui achète à tour de bras pour rattraper son retard. Les autres ne comptent pas, ont un marché de niche, ciblent les PME, ou ont été rachetés.</p>
<p><a href="http://de.wikipedia.org/wiki/SAP" hreflang="de">SAP existe depuis plus longtemps que moi</a>, tandis qu’<a href="http://en.wikipedia.org/wiki/Oracle_Corporation">Oracle</a> a longtemps basé sa réputation sur <a href="http://en.wikipedia.org/wiki/Oracle_database" hreflang="en">sa base de données</a> qui, malgré bien des défauts, est devenue <em>la</em> référence dans le domaine. Si je parle d’Oracle ici, j’entends <em>Oracle Applications</em>, pas la base de données<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/06/28/156-la-guerre-des-erp-sap-vs-oracle-applications-1-des-interfaces-hideuses#pnote-140-1" id="rev-pnote-140-1">1</a>]</sup>.</p>
<p>Je connais principalement Oracle Applications 11.0 et 11i, et, avec beaucoup moins d’expérience SAP R/3 et un peu le SAP CRM. Ce qui suit peut être dépendant du paramétrage des bases que j’ai rencontrées.</p>
<p>En passant d’Oracle à SAP, on s’aperçoit que la philosophie des deux produits est totalement opposée, même s’ils tentent de répondre aux mêmes besoins (gérer une entreprise de bonne taille de bout en bout) avec les mêmes moyens (beaucoup de MHz, de Go et de frais en licences et <em>consulting</em>).</p>
<h3>C’est hideux</h3>
<p>L’<strong>interface</strong> est aussi hideuse et anti-ergonomique chez l’un que chez l’autre, mais d’une manière totalement différente. En fait, ni l’une ni l’autre n’a vraiment évolué depuis au bas mot 1998.</p>
<ul>
<li><strong>Oracle semble avoir dix ans de retard sur le développement des interfaces graphiques à la Mac ou Windows</strong>. L’entreprise n’est pas connue pour son souci de l’ergonomie de toute manière.<br /> Depuis environ l’an 2000, l’utilisation de Java pour <em>toutes</em> les interfaces graphiques (de l’utilisateur de base à l’administrateur de la base) se traduit par une lourdeur certaine (plus supportable sur les machines actuelles), et un manque de cohérence avec les applications habituelles dans le monde Windows.<br />L’essentiel de l’ERP est resté au paradigme des <strong>fenêtres</strong> qui s’enchaînent, se chevauchent... en mode MDI (des fenêtres dans la fenêtre principale, très à la mode sous Windows 3.1). <br />Pour basculer d’une fenêtre à une autre (par exemple avoir des informations sur un article depuis l’écran d’une commande), le plus simple est encore de noter sur un papier ou dans le presse-papier ce qu’on cherche, de refermer toutes les fenêtres du module fonctionnel (!), et d’aller dans l’autre module...<br />Le passage d’une partie de l’interface au mode web est déjà effectif mais son ergonomie est pour le moins perfectible. Oracle a l’intention d’évoluer vers un modèle mixte moitié « classique » (serveurs en entreprise, licenses...) moitié « à la demande», <em>ie</em> hébergé, par le web (un peu comme <a href="http://www.salesforce.com/" hreflang="en">Salesforce</a>).</li>
</ul>
<ul>
<li><strong>SAP affiche ouvertement ses origines sur gros systèmes</strong> à une époque où l’idée d’un ordinateur sur chaque bureau relevait de la science-fiction sinon de l’utopie. Les « listes » brutes existent encore, avec les tableaux dessinés à coup de caractères de contrôle, qui autrefois s’affichaient sans doute sur un bel écran de terminal noir et vert (sinon sur du listing papier).<br />Le flux se base sur une succession d’écrans qui occupent toute la fenêtre, comme une page web, et pas comme des fenêtres séparées. À l’usage, ce n’est pas si mal.<br />Depuis le texte a été enrobé, d’absconses icônes sont apparues, quelques gadgets sont sympathiques (notamment le double-clic pour accéder à une autre information, très pratique... quand il est là), mais l’interface ferait hurler n’importe quel ergonome. Par exemple certains onglets ont l’apparence de boutons d’actions (les onglets dignes de ce nom existent aussi) : <img src="https://www.coindeweb.net/blogeclectique/images/erp/sap_commande_client.jpg" alt="Commande client SAP" style="display:block; margin:0 auto;" /><br /></li>
</ul>
<h3>Des limites énervantes partout</h3>
<p>Les limites abondent chez l’un et l’autre, qui auraient apparemment pu être levées avec un peu d’effort (mais elles sont là depuis des lustres). Quelques exemples graves ou minimes, comme ils me viennent :</p>
<ul>
<li>Le <strong>menu</strong> principal d’Oracle est du texte sous forme de menu (moche mais fonctionnel), restreint à la « responsabilité » (en gros, un module fonctionnel plus ou moins personnalisé) en cours. Les raccourcis qu’on peut y placer sont limités à dix (10), numérotés de 0 à 9. Supprimer l’un d’entre eux revient à renuméroter les autres. <br /><img src="https://www.coindeweb.net/blogeclectique/images/erp/oracle_appli_ecran_princ.jpg" alt="Écran principal Oracle" style="display:block; margin:0 auto;" /><br />Avoir plusieurs sessions simultanées d’Oracle Applications est possible en se reconnectant plusieurs fois.<br />À l’inverse, SAP offre un menu avec tous les écrans autorisés à l’utilisateur, plus les « codes transactions » (taper <code>VA03</code> pour lire les commandes, <code>VF01</code> pour créer une facture...), et la gestion simultanée de plusieurs écrans (« modes ») est facilitée.</li>
</ul>
<ul>
<li>Les <strong>raccourcis clavier</strong> sous Oracle sont assez pauvres ; sous SAP l’usage des touches de fonction est massif mais le raccourci pour une même fonctionnalité change suivant l’écran.</li>
</ul>
<ul>
<li>Les raccourcis n’ont souvent pas grand-chose en commun avec ceux répandus sous Windows ou ailleurs.</li>
</ul>
<ul>
<li>SAP prend un malin plaisir à rendre difficile le <strong>pointage de souris</strong>. Les boutons de boîtes de dialogue sont petits, les boutons par défaut ne sont pas plus grands que les autres, et, cerise sur le gâteau, une grosse icône SAP remplace les habituels trois petits boutons Réduire/Agrandir/Fermer de toute fenêtre de Windows, lesdits boutons étant décalés plus à gauche, en réduction, pour bien être sûr de mal viser. (Voir copie d’écran ci-dessous.)<br />Oracle n’a pas ce défaut, les boutons sont moches mais décemment dimensionnés. Par contre, inutile de chercher à agrandir ou réduire une fenêtre pour avoir plus de colonnes/lignes à l’écran, ce n’est pas prévu.</li>
</ul>
<ul>
<li>Nombre des écrans d’Oracle sont <strong>accessibles en écriture comme en lecture</strong>, pas de juste milieu (apparemment et simplement en tout cas). Dans le cadre de la restriction généralisée et paranoïaque des accès (<a href="http://en.wikipedia.org/wiki/Sarbanes-Oxley" hreflang="en">Sarbanes-Oxley</a> et <em>tutti quanti</em>), c’est très gênant.<br />SAP a généralisé (au moins dans les vieux modules) le principe de transactions (entrées de menu) différentes selon qu’on veut créer, modifier, ou juste voir, une commande, un article...</li>
</ul>
<ul>
<li>La <strong>traduction française</strong> est désastreuse sur SAP (je connais Oracle surtout en version originale). La grammaire est correcte, mais je comprends souvent mieux en version allemande ou anglaise, un comble ! Entre autres détails : en français, on dit « <em>Annuler</em> » pour sortir sans rien faire d’une boîte de dialogue (comme en anglais : “<em>Dismiss</em>” ou “<em>Cancel</em>”), pas « <em>Interrompre</em> » (»<em>Abbrechen</em>« en allemand) !<br />Que des morceaux d’allemand surnagent par-ci par-là dans les modules techniques, ou que des morceaux de phrases aient sauté de-ci de-là, est paradoxalement moins grave.</li>
</ul>
<ul>
<li>SAP abuse des <strong>abréviations</strong> dans les noms de colonne ou de champ, jusqu’à l’absurde (« C. » comme nom de colonne !). Y compris dans les infobulles, sisi. <br />Oracle connaît peu les infobulles mais en général remplit moins ses écrans.</li>
</ul>
<ul>
<li>L’<strong>aide</strong> en ligne des deux concurrents pèche de la même manière : correcte dans un sens descriptif, insuffisante comme base de travail pour chercher comment retrouver ou paramétrer tel ou tel objet (il faut reconnaître que l’exhaustivité serait titanesque à obtenir).</li>
</ul>
<ul>
<li>(SAP) Pour imprimer une facture, il ne faut surtout pas cliquer sur le symbole vert qui signifie « <em>OK</em> » dans la boîte de dialogue après un clic sur «<em> Éditer</em> », mais sur l’icône de l’imprimante. Le bouton vert ne <em>sert à rien</em> !<img src="https://www.coindeweb.net/blogeclectique/images/erp/SAP-facture-editer.png" alt="Édition de facture sous SAP" style="display:block; margin:0 auto;" /></li>
</ul>
<ul>
<li>Pour le développeur : dans l’éditeur de code ABAP (imposé, oubliez <a href="http://www.eclipse.org/" hreflang="en">Eclipse</a>, <a href="http://www.vim.org/" hreflang="en">vi</a>, <a href="http://www.nedit.org/" hreflang="en">nedit</a>...), les commentaires sont en bleu... s’ils sont déclarés avec une étoile sur le premier caractère de la ligne. Si le commentaire se trouve sur la même ligne que du code, séparé par un <code>"</code>, ils ne bénéficient pas de la coloration syntaxique !<br />On prend donc vite l’habitude d’aérer le code ABAP (déjà très verbeux) par des commentaires seuls sur leur ligne. Ce n’est pas si gênant, car de toute façon l’éditeur ne supporte pas les lignes de plus de 72 caractères (le standard en 1983) !<img src="https://www.coindeweb.net/blogeclectique/images/erp/sap_editeur_commentaires.jpg" alt="Éditeur ABAP" style="display:block; margin:0 auto;" /></li>
</ul>
<ul>
<li>SmartForms, un module de SAP de développement de formulaire<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/06/28/156-la-guerre-des-erp-sap-vs-oracle-applications-1-des-interfaces-hideuses#pnote-140-2" id="rev-pnote-140-2">2</a>]</sup> possède des fenêtres avec ascenseur au sein d’autres fenêtres avec ascenseur ! Une monstruosité ergonomique que je n’ai jamais rencontré qu’au sein de pages web qui n’avaient pas le choix de faire autrement. Smartforms n’est pourtant pas un vieux clou traîné depuis vingt ans, mais un outil très récent de SAP - ce sont souvent les pires (en complexité inutile surtout).</li>
</ul>
<ul>
<li>Smartforms (encore lui) ne gère pas les différentes versions d’un objet, alors que la notion de gestion de versions est intégrée à l’éditeur des programmes ABAP depuis des années. Au passage, cela rend cauchemardesque la simple annulation de modifications... Chaque outil de développement a été ajouté sans grand respect pour la cohérence avec les outils précédents.</li>
</ul>
<ul>
<li>Etc. etc. <br />Ce ne sont que des détails, mais mis bout à bout ils me tapent sur les nerfs. Ils résument bien la philosophie des produits et la manière dont il sont conçus et vendus.</li>
</ul>
<h3>Quelques gadgets sympas</h3>
<p>C’est surtout SAP qui les possède (<strong>Mise à jour de 2008</strong>: <a href="https://www.coindeweb.net/blogeclectique/index.php?post/2008/10/04/194-les-bonnes-idees-de-sap">voir aussi ce billet</a> ) :</p>
<ul>
<li>le double-clic déjà évoqué pour avoir plus d’information sur tel ou tel objet (mais il n’est pas toujours là) ;</li>
</ul>
<ul>
<li>les <em>matchcodes</em>, des petits sous-écrans qui permettent de faire des sélections de plages de valeurs un peu tordues (du genre « prendre les codes articles 1023 à 8123 sauf les 4526 à 5622, et pas le 8001 »), et bien intégrés au langage ABAP sous-jacent ; Oracle ne connaît que les plages de valeur simples ;</li>
</ul>
<ul>
<li>SAP mémorise les dernières valeurs entrées dans un champ ; si vous manipulez les dix mêmes articles/commandes/programmes, ils sont automatiquement proposés dans un menu déroulant à chaque saisie ;</li>
</ul>
<ul>
<li>Hélas, si l’interface de SAP est supportable après un peu d’apprentissage par un utilisateur, <a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/06/30/177-la-guerre-des-erp-sap-vs-oracle-applications-2-deux-gros-patchworks">celle réservée au développeur « sous le capot » fait nettement plus peur</a>…</li>
</ul>
<p>Partie 1 : Des interfaces hideuses</p>
<p><a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/06/30/177-la-guerre-des-erp-sap-vs-oracle-applications-2-deux-gros-patchworks">Partie 2 : Deux gros patchworks</a></p>
<p><a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/07/03/178-la-guerre-des-erp-sap-vs-oracle-applications-3-des-interfaces-tres-particulieres">Partie 3 : Des interfaces très particulières</a></p>
<p><a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/07/04/176-la-guerre-des-erp-sap-vs-oracle-applications-4-philosophie-opposees">Partie 4 : Philosophies opposées</a></p>
<p><a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/07/05/175-la-guerre-des-erp-sap-vs-oracle-applications-5-schemas-de-donnees">Partie 5 : Schémas de données</a></p>
<div class="footnotes"><h4>Notes</h4>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/06/28/156-la-guerre-des-erp-sap-vs-oracle-applications-1-des-interfaces-hideuses#rev-pnote-140-1" id="pnote-140-1">1</a>] <em>De toute façon, SAP utilise en général Oracle (la base) en arrière-plan...</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/06/28/156-la-guerre-des-erp-sap-vs-oracle-applications-1-des-interfaces-hideuses#rev-pnote-140-2" id="pnote-140-2">2</a>] <em>Dans le sens « bout de papier à imprimer » ; pour compliquer les choses, les terminologies de « rapport » et « formulaire » sont à peu près opposées entre les deux concurrents...</em></p></div>
https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/06/28/156-la-guerre-des-erp-sap-vs-oracle-applications-1-des-interfaces-hideuses#comment-formhttps://www.coindeweb.net/blogsanssujetprecis/index.php?feed/atom/comments/140Les joies de l’ERP et du CRM (III)urn:md5:7a2776e3fbd62d5c93d7c149b8ad70fc2006-03-14T10:37:00+00:002010-10-26T20:04:17+00:00ChristopheInformatique lourdebase de donnéescomplexitédéveloppementERPexpertiseinformatiqueintelligence artificiellelogistiquemicroéconomieOracleorganisationparadoxeperfectionnismeperspectiveprise de têteprécisionSAPSSIItravailvaleuréconomie<p>Suite des maux de tête liés au fonctionnement normal d’une entreprise et de son informatique.</p> <p><a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/03/10/88-les-joies-de-l-erp-et-du-crm-ii">Nous avons vu le genre de céphalée que peut représenter une simple commande quand on a plusieurs intermédiaires et prestataires impliqués</a>.</p>
<p>Avec un peu d’aspirine, tous ces concepts finissent <strong>modélisés</strong> sous forme de <strong>tables</strong> informatiques dans une grosse base de données SQL. Les ERP fournissent d’ailleurs la solution clés en main, dont la compréhension est à peu près aussi longue et pénible que tout recréer soi-même (au moins est-ce débogué).</p>
<p>Il faut ensuite se poser la question de remplir les données. Si on agit au fil de l’eau (l’administration des ventes ou un télévendeur remplit tout sur le champ), on court le risque de voir des <strong>doublons</strong> dans son fichier client. Dans certaines branches on a le luxe de recevoir une <strong>liste de ses clients finaux</strong>, soigneusement numérotés, avec leurs adresses, de la part du donneur d’ordres ou d’un intermédiaire financier ou technique.</p>
<p>L’<strong>erreur est de croire que l’on peut intégrer aveuglément cette liste</strong> extérieure dans sa base de clients. Les adresses notamment doivent éveiller la plus grande méfiance<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/14/116-les-joies-de-l-erp-et-du-crm-iii#pnote-109-1" id="rev-pnote-109-1">1</a>]</sup>.</p>
<p>Si la liste est propre, elle comprendra deux ou trois champs d’adresse séparés des codes postaux et des noms de ville.
<br />Si elle ne l’est pas (par exemple si elle provient d’une certaine multinationale que je ne citerai pas<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/14/116-les-joies-de-l-erp-et-du-crm-iii#pnote-109-2" id="rev-pnote-109-2">2</a>]</sup>), il faudra quasiment développer une <strong>intelligence artificielle</strong> capable de différencier un code postal d’un code TVA dans le magma informe que ces champs d’adresse seront devenus. Il est en général plus efficace de laisser une secrétaire revoir <strong>manuellement</strong> ces adresses. <br />S’il y en a dix mille, couvrant cinquante pays dans le monde, la tâche devient « intéressante » dans le sens démoniaque du terme.<br />Il existe des logiciels interfacés avec les bases de données de la Poste et de ses équivalents étrangers, pour reformater automatiquement ces adresses. J’ignore leur prix, il doit être aussi indécent que leur utilité est grande.</p>
<p>Pour corser la chose, cette liste ne comprend pas uniquement les clients mais aussi leurs premières commandes<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/14/116-les-joies-de-l-erp-et-du-crm-iii#pnote-109-3" id="rev-pnote-109-3">3</a>]</sup>, et de gros problèmes de <strong>conversion de jeux de caractères</strong> entre l’Excel en Unicode et l’Oracle en Latin-9<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/14/116-les-joies-de-l-erp-et-du-crm-iii#pnote-109-4" id="rev-pnote-109-4">4</a>]</sup>.</p>
<p>Reprenons notre commande. Elle peut se réduire à une ligne d’un article avec une quantité, un prix. Que ce soit 1 ampoule à 0,5 € ou 200 palettes de téléphones portables à 1000 € pièce, la complexité informatique est la même. Elle
peut donc sembler simple à gérer au premier abord. Mais beaucoup de choses peuvent se dérouler par derrière :</p>
<ul>
<li>Certains systèmes (SAP notamment) rajoutent une notion d’<strong>échéances</strong> en dessous de la notion de ligne de commande. Il peut y en avoir beaucoup quand il s’agit de livraisons étalées sur des mois. La commande doit donc être <strong>partiellement livrée</strong> et payée avant même d’être totalement renseignée.<br />On notera au passage qu’il n’y a absolument pas de rapport de un-pour-un entre commande et livraison, ni entre commande et facture (on est déjà content si ce rapport existe au niveau de la ligne ou de l’échéance).<br /></li>
</ul>
<ul>
<li>Un <strong>conteneur</strong> peut être consigné et ajouté automatiquement (à la commande d’une caisse de bières par exemple), et ce même conteneur être récupéré à la livraison suivante, pour donner lieu à une <strong>déconsigne</strong> qui, subtilité, n’apparaîtra pas forcément sur la <em>commande</em> mais uniquement sur la <em>facture</em>.<br />Le terme <em>facture</em> est lui-même trompeur, car un livreur n’arrive qu’avec un borderau de livraison (ou facture <em>pro forma</em>) et la vraie facture comptable, comprenant les déconsignes, et faisant foi auprès de l’administration, n’est jamais imprimée.<br />Subtilité : le numéro de cette facture n’existe pas au moment où le client reçoit la <em>pro forma</em>, ce qui pose d’intéressants problèmes de rapprochements si le client paye dès la réception...<br /></li>
</ul>
<ul>
<li>L’unité à prendre en compte peut être l’<strong>unité</strong> (objets manufacturés), une unité de volume classique (le litre), ou qui dépend d’une autre et qui dépend de l’article (dans la distribution de boissons, un <em>col</em> peut faire 0,30 comme 1,75 litre, une <em>caisse</em> peut faire 12 cols, etc.). <br /></li>
</ul>
<ul>
<li>La mise en place du <strong>calcul du prix</strong> est un poème ; certains consultants y consacrent leur vie : prix de base (dans quelle unité ?), remise sur quantité, remise <em>positive</em> (qui permet d’afficher des prix artificiellement bas), frais de transports, frais de facturation, marges arrières plus ou moins claires, attribution gratuite d’articles en plus ou au sein de la quantité commandé... tout ceci variant dans le temps, l’espace, la sous-société qui reçoit la commande, la tête du client final et sa capacité de négociation, les habitudes de tel ou tel commercial et les traditions des différents services.<br /></li>
</ul>
<ul>
<li>Il est rare qu’il y ait de vente sans commercial. Celui-ci exigera peut-être sa part, et le système stockera quelque part la <strong>commission</strong> qu’il doit toucher. Lui aussi doit être payé.<br /></li>
</ul>
<ul>
<li>De même, le prix annoncé au client n’est pas forcément celui qui sera payé au fournisseur si un <strong>intermédiaire</strong> quelconque prélève sa commission (grande centrale, groupement, ou simplement affacturage).<br /></li>
</ul>
<ul>
<li>Murphy oblige, <em>la</em> <strong>fonctionnalité critique</strong> du cœur de métier du client, qui ne se rencontre nulle part ailleurs, n’est pas prévue dans le logiciel. Ou alors elle possède une limitation majeure (à première vue arbitraire et débile mais liée à l’historique de développement de l’ERP).<br /> C’est là qu’intervient la SSII, qui bénit le client pour ses excentricités, et maudit l’éditeur pour la difficulté d’adaptation (quoiqu’il faille distinguer entre le développeur qui s’arrache les cheveux et le commercial qui s’en moque, il a fait son boulot de décrocheur de contrat).</li>
</ul>
<div class="footnotes"><h4>Notes</h4>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/14/116-les-joies-de-l-erp-et-du-crm-iii#rev-pnote-109-1" id="pnote-109-1">1</a>] <em>Toute donnée envoyée par un intermédiaire est indigne de confiance d’ailleurs.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/14/116-les-joies-de-l-erp-et-du-crm-iii#rev-pnote-109-2" id="pnote-109-2">2</a>] <em>Les grosses entreprises ne sont pas mieux organisées ou rigoureuses que les petites ; je pencherai parfois pour le contraire.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/14/116-les-joies-de-l-erp-et-du-crm-iii#rev-pnote-109-3" id="pnote-109-3">3</a>] <em>En clair : petit informaticien, débrouille-toi </em>fissa<em> pour intégrer le fichier dans Oracle, tu n’as </em>pas<em> le temps de réfléchir à un beau modèle de données et à un import par étapes.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/14/116-les-joies-de-l-erp-et-du-crm-iii#rev-pnote-109-4" id="pnote-109-4">4</a>] <em>Encore a-t-on bien moins de problèmes avec cela ces temps-ci. De toute manière, le VRAI problème viendra en fait du fichier extérieur, </em>déjà<em> vérolé par des conversions hasardeuses lors de son détour au sein d’une base de données nord-américaine préhistorique qui ne comprend que l’ASCII sur 7 bits, et remplace les é, à, ñ, ß et Ç par des carrés blancs ou des traits verticaux.</em></p></div>
https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/14/116-les-joies-de-l-erp-et-du-crm-iii#comment-formhttps://www.coindeweb.net/blogsanssujetprecis/index.php?feed/atom/comments/109Les joies de l’ERP et du CRM (II)urn:md5:5181f1ed31ea14b6c301fd2850f59eba2006-03-10T20:30:00+00:002014-02-26T10:32:05+00:00ChristopheInformatique lourdebase de donnéescomplexitéCRMdéveloppementERPexpertiseinformatiquelangueslogistiqueOracleorganisationprise de têteprécisionSAPtravail<p>ERP et CRM sont conçus pour gérer les cas les plus tordus et ils rajoutent. Le CRM a des joies cachées pour les amateurs de puzzle, de casse-têtes et de barbarismes linguistiques</p> <p>Nous avons vu récemment que <a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/10/blogsanssujetprecis//index.php?post/2006/03/04/87-les-joies-de-l-erp-et-du-crm-i">la complexité des ERP, combiné à un lourd passé, en faisaient des monstres ruineux et techniquement assez cryptiques</a>.</p>
<p>En tant que développeur il y a bien pire que les termes barbares du système à assimiler : il faut
comprendre ce que l’<em>utilisateur</em> veut faire avec le système. (Comme de plus c’est lui paye, c’est lui qui commande).<br />Pour le naïf technicien
qui débarque en plein dans un flux logistique, le monde un peu flou de la vente et des
livraisons prend soudain sa pleine dimension.
<br />Au début il s’imagine qu’une commande ne doit pas être si tordue à concevoir dans un modèle
de données bien propre :</p>
<ul>
<li>on commence par un <strong>en-tête</strong> avec quelques informations : le <strong>client</strong>, son <strong>adresse</strong>, le numéro de la <strong>facture</strong> ;</li>
<li>on enchaîne avec les <strong>lignes</strong> de commandes : un objet ou un service, une quantité, un prix unitaire ;</li>
<li>on termine en sommant les lignes, on rajoute la TVA ;</li>
<li>il reste éventuellement à <strong>livrer</strong> à l’adresse du client…</li>
</ul>
<p>Commençons par les <strong>adresses</strong>. Si on veut tout prévoir, il faut distinguer d’abord l’adresse de
<strong>livraison</strong> de l’adresse de <strong>facturation</strong>. N’importe quel site de commerce en ligne
est à présent capable de gérer la différence : vous pouvez ainsi envoyer un cadeau de Noël à votre chère grand-mère tout en recevant vous-même la facture papier.</p>
<p>Mais cela peut être encore plus compliqué ; par exemple :</p>
<ul>
<li>l’usine <code>TARTEMPION</code>, en France ;</li>
<li>peut recevoir une commande de <code>TOTO GmbH</code> (« donneur d’ordres » européen) ;</li>
<li>au nom de la PME brésilienne <code>PEDRO</code> (« destinataire final » des biens physiques) ;</li>
<li>à facturer à <code>TOTO Bizness International</code> (entité comptable du groupe <code>TOTO</code>, « destinataire de la facture ») ;</li>
<li>et qui sera effectivement payée par <code>TOTO Bank Ltd</code> (« payeur ») ;</li>
<li>à <code>VITENCAISSE</code>, société d’<a href="http://www.netpme.fr/banque-entreprise/2-l-affacturage.html">affacturage</a> qui sous-traite la facturation (relances, frais, avance, garantie de paiement…) de <code>TARTEMPION</code> ;</li>
<li>la livraison ne sera pas à envoyer directement au Brésil, mais à un <strong>intermédiaire logistique</strong> (« client délivré »), disons <code>FedDHL</code> à Amsterdam.</li>
</ul>
<p>Les ordinateurs de TARTEMPION, se doivent donc, pour une unique commande, <strong>créer chacune de ces entités</strong>, et ne pas perdre les <strong>liens</strong> entre elles. Il est mal vu et parfois coûteux d’envoyer une facture papier au lieu d’une palette, ou de réclamer le paiement à celui qui sert juste de livreur.</p>
<p>Renseigner tout cela à la main devient vite pénible, d’autant plus que les ERP sont rarement des monstres d’ergonomie<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/10/88-les-joies-de-l-erp-et-du-crm-ii#pnote-89-1" id="rev-pnote-89-1">1</a>]</sup>. Mais on atteint le cauchemar lorsque la création d’adresses ou clients doit être <strong>automatisée</strong> et que les données adéquates doivent se remplir spontanément sur les écrans informatiques de l’administration des ventes. Au passage on se demande qui là-dedans est vraiment le sacro-saint « client »<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/10/88-les-joies-de-l-erp-et-du-crm-ii#pnote-89-2" id="rev-pnote-89-2">2</a>]</sup>.</p>
<p>Avec le <strong>jargon</strong> adéquat, mélangé à l’anglais imposé par certaines multinationales à leurs filiales, on aboutira au final à la conclusion que TOTO Bank Ltd est le <em>PayTo From</em> de PEDRO, et TOTO Bizness International le <em>BillTo Of</em> de TOTO GmbH<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/10/88-les-joies-de-l-erp-et-du-crm-ii#pnote-89-3" id="rev-pnote-89-3">3</a>]</sup>. Le CRM a des joies cachées pour les amateurs de puzzle, de casse-têtes et de barbarismes linguistiques.</p>
<p>Ce n’est que le début. Inutile de dire que PEDRO, TOTO Bank ou VITENCAISSE ont chacun une demi-douzaine d’<strong>adresses physiques</strong> (prévoir la notion d’« adresse primaire »), chacune dédiée à un rôle différent, ou pas (rajoutons une table des « usages d’adresse »). Certaines de ces adresses peuvent être celles d’une autre entité d’ailleurs (stock déporté par exemple).</p>
<p><em><a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/03/14/116-les-joies-de-l-erp-et-du-crm-iii">À suivre…</a></em></p>
<div class="footnotes"><h4 class="footnotes-title">Notes</h4>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/10/88-les-joies-de-l-erp-et-du-crm-ii#rev-pnote-89-1" id="pnote-89-1">1</a>] <em>Ils en violent même la plupart des règles.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/10/88-les-joies-de-l-erp-et-du-crm-ii#rev-pnote-89-2" id="pnote-89-2">2</a>] <em>Et se poser cette question, c’est se poser celle de l’entité à qui il faut plaire en priorité : l’utilisateur final ou l’un de ces intermédiaires qui ne l’ont peut-être jamais vu ?</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/10/88-les-joies-de-l-erp-et-du-crm-ii#rev-pnote-89-3" id="pnote-89-3">3</a>] <em>Exemple immonde inspiré d’Oracle Applications.</em></p></div>
https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/10/88-les-joies-de-l-erp-et-du-crm-ii#comment-formhttps://www.coindeweb.net/blogsanssujetprecis/index.php?feed/atom/comments/89Les joies de l’ERP et du CRM (I)urn:md5:a7c454065eeee45c7c4de584724238a02006-03-04T16:34:00+00:002010-10-26T14:25:44+00:00ChristopheInformatique lourdeargentbase de donnéescomplexitéergonomieERPexpertiseimpérialismeinformatiquelangueslogistiqueOracleorganisationSAPSQLSSIItravailvaleuréconomie<p>Un ERP est un monstre coûteux et souvent abscons.</p> <p>Un <a href="http://www.commentcamarche.net/entreprise/erp.php3">ERP</a> est un monstre. C’est un logiciel coûteux, voire ruineux, souvent très lourd à mettre en place, qui impose sa logique à toute une entreprise, mais qui lui permet d’intégrer tout son fonctionnement de A à Z : commandes clients, livraison, production, facturation, plans de prod, achats, ressources humaines, calcul de coûts, marges, rapports fiscaux et comptables, qualité... <br />Des armées de consultant consacrent leur vie à la mise en place et la maintenance des ERP - et ils ont fait la fortune de bien des <a href="http://www.top50-ssii.com/">SSII</a>. <sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/04/87-les-joies-de-l-erp-et-du-crm-i#pnote-87-1" id="rev-pnote-87-1">1</a>]</sup> <img src="https://www.coindeweb.net/blogeclectique/images/erp/sap-buchung.jpg" alt="sap-buchung.jpg" style="float:right; margin: 0 0 1em 1em;" title="SAP" /></p>
<p>Le <a href="http://www.commentcamarche.net/entreprise/crm.php3">CRM</a> est un autre terme fourre-tout pour un logiciel censé gérer toute la « relation client »<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/04/87-les-joies-de-l-erp-et-du-crm-i#pnote-87-2" id="rev-pnote-87-2">2</a>]</sup>, de la commande au service après-vente. C’est effectivement un monde très vaste et le terme veut dire un peu tout et rien. C’est souvent un des modules d’un ERP. Comme lui, il a besoin de doses massives de paramétrage pour s’adapter aux besoins de l’utilisateur.</p>
<p>Ça fait quelques années que je me casse le crâne sur les commandes et livraisons dans des ERP,
que ce soit <a href="http://www.oracle.com/fr/">Oracle Applications</a> ou plus récemment <a href="http://www.sap.com/france/">SAP</a>.</p>
<p>Techniquement, les entrailles de ces monstres sont assez glauques. On sent l’historique
chargé<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/04/87-les-joies-de-l-erp-et-du-crm-i#pnote-87-3" id="rev-pnote-87-3">3</a>]</sup>. Par exemple, la table des articles dans SAP se nomme <code>MARA</code>, celle des commandes
<code>VBAK</code>, celle des livraisons <code>LIKP</code>, celle des pays <code>T005</code>. <br />La première impression d’horreur est totalement justifiée : ces codes datent bien de la préhistoire de l’informatique,
de l’ère où les noms de fichiers (ne parlons pas alors de « tables ») se limitaient à 4 caractères<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/04/87-les-joies-de-l-erp-et-du-crm-i#pnote-87-4" id="rev-pnote-87-4">4</a>]</sup>. Il y a tout de même quelques trucs mnémotechniques : le « K » dans <code>VBAK</code> et le « KP » dans <code>LIKP</code> veulent dire « en-tête »... en allemand (<em>kopf</em>). Oui, SAP est allemand<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/04/87-les-joies-de-l-erp-et-du-crm-i#pnote-87-5" id="rev-pnote-87-5">5</a>]</sup>.</p>
<p>Dans la même logique, on verra vite que les tables de lignes de commandes et de livraisons correspondant à ces en-têtes s’appellent <code>VBAP</code> et <code>LIPS</code>. P et PS pour « poste » (<em>Position</em> outre-Rhin), évidemment ; ce serait trop simple de parler de « lignes » de commandes. Si vous ignoriez le terme dans ce contexte, je vous l’apprends, et je l’ignorais moi-même il y a deux mois.</p>
<p><img src="https://www.coindeweb.net/blogeclectique/images/erp/oracle_appli.jpg" alt="oracle_appli.jpg" style="float:left; margin: 0 1em 1em 0;" title="oracle_appli.jpg" /> Le concurrent, Oracle Applications, est un peu plus bavard quant aux noms de tables : <code>OE_ORDER_LINES</code>
et <code>OE_ORDER_HEADERS</code>, <code>WSH_DELIVERIES</code>, <code>WSH_DELIVERY_DETAILS</code> sont beaucoup plus explicites.
Et il y a plus de chances que vous parliez anglais qu’allemand. (Par contre, l’interface utilisateur
est tellement moche qu’un commercial m’a dit éviter de la présenter en avant-vente<sup>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/04/87-les-joies-de-l-erp-et-du-crm-i#pnote-87-6" id="rev-pnote-87-6">6</a>]</sup>.).</p>
<p><em><a href="https://www.coindeweb.net/blogeclectique/index.php?post/2006/03/10/88-les-joies-de-l-erp-et-du-crm-ii">À suivre...</a></em></p>
<div class="footnotes"><h4>Notes</h4>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/04/87-les-joies-de-l-erp-et-du-crm-i#rev-pnote-87-1" id="pnote-87-1">1</a>] <em>D’ailleurs, la difficulté de modification, de paramétrage et de maintenance des ERP sont une des raisons pour lesquelles les SSII adorent les vendre : ils s’assurent ainsi une éternelle réserve de facturation toutes les années où l’ERP tournera. Les clients ne résistent souvent pas à la tentation de vouloir adapter l’outil à leurs habitudes, même si on calcule que le plus ridicule rapport ou écran coûtera plusieurs milliers d’euros.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/04/87-les-joies-de-l-erp-et-du-crm-i#rev-pnote-87-2" id="pnote-87-2">2</a>] <em>S’il n’y a pas de préposition, c’est de l’anglais traduit par quelqu’un qui voulait impressionner son monde.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/04/87-les-joies-de-l-erp-et-du-crm-i#rev-pnote-87-3" id="pnote-87-3">3</a>] <em>Le cœur de chacun de ces produits est en général très ancien, <a href="http://emploi.journaldunet.com/magazine/713/">parfois trois décennies</a> ; même s’il a été reprogrammé depuis, les anciennes modes et contraintes de programmation et d’interface y ont imprimé leur marque pour toujours. De plus, un module est souvent un logiciel tiers acheté, plus ou moins bien intégré au reste de l’ERP. Enfin, des modules récents cohabitent avec des modules antédiluviens car anciens et stables (souvent la comptabilité), ce qui occasionne de belles incohérences de logiques d’interface ou de programmation.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/04/87-les-joies-de-l-erp-et-du-crm-i#rev-pnote-87-4" id="pnote-87-4">4</a>] <em>De manière plus récente, certaines normes de nommage de documents sont encore influencées par celles de DOS et Windows 3.1 (8 caractères maxi), dix ans après leur disparition.</em>.</p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/04/87-les-joies-de-l-erp-et-du-crm-i#rev-pnote-87-5" id="pnote-87-5">5</a>] <em>Et le code source des programmes est bourré de commentaires dans la langue de Goethe. Je suis très heureux de la parler.</em></p>
<p>[<a href="https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/04/87-les-joies-de-l-erp-et-du-crm-i#rev-pnote-87-6" id="pnote-87-6">6</a>] <em>Qu’une interface soit moche est trompeur. Celle d’Oracle est plus consistante bien que plus limitée que SAP. Mais je crois que je les hais toutes les deux.</em></p></div>
https://www.coindeweb.net/blogsanssujetprecis/index.php?post/2006/03/04/87-les-joies-de-l-erp-et-du-crm-i#comment-formhttps://www.coindeweb.net/blogsanssujetprecis/index.php?feed/atom/comments/87