IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Développement SQL Server Discussion :

Insérer des données dans une colonne trop petite [2016]


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut Insérer des données dans une colonne trop petite
    Bonjour,

    J'ai un souci récurrent en SQL, et je me demande s'il n'y a pas une solution "simple" à mettre en place.

    Mettons une table des clients (id, code, nom, prenom, etc.)

    Je dois m'interfacer avec un autre serveur.

    Je récupère donc dans une base tampon toutes les données du serveur distant, puis je fais un différentiel entre ce qui a été modifié, ajouté et supprimé.

    Et je recopie les lignes en écart.

    Du coup je vais ça à grand coup de INSERT from SELECT.
    Et la base distante étant une petite rigolote, des fois j'ai des changements de type sans être notifié, et du jour au lendemain je me retrouve à insérer dans ma table tampon des varchar(50) dans une colonne varchar(10) et ça plante.

    Existe-t-il un moyen, qui ne soit pas une usine à gaz (genre pas tester la longueur de chaque colonne une à une) qui permette non pas de planter la requête, mais simplement ignorer les lignes en erreur, soit en alimentant une table de rejet (l'idéal) soit simplement en déclenchant un message d'erreur qui ne soit pas bloquant (et qui ne fasse donc pas échouer le reste de la requête) ?

    Car actuellement, je suis obligé de détecter quand ma requête échoue, et mon interface reste complètement bloquée jusqu'à ce que je corrige (ce que je ne peux pas toujours faire dans l'immédiat) et si je détecte mal l'anomalie, je me retrouve avec une table tampon vide, donc mon programme croit qu'il faut vider la table des clients et là c'est tout de suite moins drôle.

    La solution alternative consisterait à traiter les lignes 1 à 1 de manière séquentielle... Mais là d'un traitement de 2 minutes plus plusieurs centaines de milliers de clients, on va passer à 4 heures...

    L'idéal serait d'avoir une comme un peu comme MERGE sauf qu'au lieu de tester l'existence d'une ligne par exemple pour faire un insert ou update, ce serait de tester l'erreur lors de l'insertion de la ligne, et de faire autre-chose si l'insert échoue.

  2. #2
    Membre expérimenté Avatar de TheRussian
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    200
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 200
    Par défaut
    Bonjour,

    sur la même problématique, intégrer les données de plusieurs applications dans un seul entrepôt de données avec les contraintes suivantes :
    - Pas informer des évolutions/modifications des appli tiers
    - Obligation d'intégrer toutes les lignes, les écarts devant être constatés sur les différents reporting à posteriori

    ==> j'ai opté pour la mise à jour des formats des colonnes dans les procédures d'importation. Et cela n'a pas été si lourd que ça. Je m'attendais à pire

    Sinon en jouant avec les TRY .. CATCH https://docs.microsoft.com/fr-fr/sql...h-transact-sql
    Il doit y avoir moyen de mettre en place ce mode de fonctionnement non ?

  3. #3
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    Le TRY CATCH s'applique à la requête entière.

    Donc quand je fais un INSERT FROM SELECT qui porte sur des millions de lignes, il suffit d'une seule ligne en erreur pour que toute l'instruction soit arrêtée.

    Ceci peut se produire au bout de plusieurs minute ou heures de traitement, c'est donc pas terrible pour ensuite :
    - Identifier les quelques lignes qui posent problème
    - Il faut rejouer toutes les autres lignes, après une grosse perte de temps

    Après effectivement, je pourrais interroger les lignes de la table source, ou parcourir le fichier d'import pour vérifier la taille max des colonnes à l'avance, mais ça fait un peu usine à gaz;

    Tant pis Pour le moment on va continuer comme ça… Le prochain coup le client mettra peut-être un peu plus de 3 mois avant de se rendre compte que l'interface est plantée

  4. #4
    Membre expérimenté Avatar de TheRussian
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    200
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 200
    Par défaut
    Une solution pourrait-être d'insérer toutes les lignes en tronquant les champs concernés avec la fonction LEFT.
    C'est un peu crade comme méthode mais cela permettra de tout charger tout le temps.

    Plus propre : Si le but est d'identifier les lignes en erreur et de ne pas les charger peut-être qu'un fonctionnement via un ETL pourrait convenir.
    On peut faire des imports et identifier les rejets tout en continuant le chargement des lignes valides.
    Tu pourrais avoir un fichier contenant tous les rejets à la fin du traitement.

  5. #5
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Décembre 2013
    Messages
    4 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Conseil

    Informations forums :
    Inscription : Décembre 2013
    Messages : 4 235
    Par défaut
    Oui, via un ETL, ça insère les bonnes lignes, et ça rejette les mauvaises.

    Sinon : Insert into matable select * from autreTable where len(description) <= 10 ;

  6. #6
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    Merci pour vos réponses

    En fait, le but ici c'est de se passer de l'ETL (notamment pour maximiser la vitesse de traitement).

    Pour ce qui est des LEFT / LEN, c'est effectivement une piste envisageable.
    Seulement le but serait de rendre la longueur du champ dépendante de la longueur physique dans la table.

    Un peu comme ce qu'on peut faire dans Oracle quand on crée une procédure stockée : au lieu d'utiliser un type nommé + longueur, on peut indiquer qu'on veut utiliser le même type qu'une colonne d'une table donnée : du coup si la colonne change, la procédure aussi.

    C'est un peu le même mécanisme que je cherche à reproduire : qu'à chaque modification ce ne soit pas une usine à gaz à faire évoluer.

    Je pense que je vais devoir passer par une génération à la volée du SQL à partir d'un programme autre que mon *.BAT actuel, tant pis

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 14/06/2013, 15h09
  2. Mise à jour des données dans une colonne
    Par BZH75 dans le forum SQL
    Réponses: 9
    Dernier message: 09/01/2008, 16h18
  3. [SQL] Insérer des données dans une table
    Par wonga dans le forum PHP & Base de données
    Réponses: 11
    Dernier message: 01/08/2007, 12h00
  4. Insérer des données dans une BD depuis un fichier .bat
    Par kurkaine dans le forum SQL Procédural
    Réponses: 3
    Dernier message: 24/11/2006, 08h31
  5. Réponses: 26
    Dernier message: 01/07/2006, 13h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo