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 :

récupérer le ou les identifiants qui ont été "mangés" par une erreur


Sujet :

Développement SQL Server

  1. #1
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 242
    Points
    4 242
    Par défaut récupérer le ou les identifiants qui ont été "mangés" par une erreur
    Hello,

    Un petit problème particulier...

    Soit la DB suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    CREATE SCHEMA S_TEST;
    GO
     
    CREATE TABLE S_TEST.T_TEST_TST(
        ID        INT    IDENTITY(1,1) NOT NULL PRIMARY KEY,
        VAL        INT NOT NULL
    );
    GO
     
    CREATE FUNCTION S_TEST.CK() RETURNS INT
    AS
    BEGIN
        DECLARE @RESULT INT;
        SELECT @RESULT = SUM(VAL) FROM S_TEST.T_TEST_TST
        RETURN @RESULT;
    END
    GO
     
    ALTER TABLE S_TEST.T_TEST_TST WITH CHECK ADD CONSTRAINT CK_SUM_VAL_LOWER_THAN_1000 CHECK (S_TEST.CK() < 1000);
    Ensuite, si je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    INSERT INTO S_TEST.T_TEST_TST(VAL)
    VALUES(500)
    GO
     
    INSERT INTO S_TEST.T_TEST_TST(VAL)
    VALUES(300)
    GO
     
    INSERT INTO S_TEST.T_TEST_TST(VAL)
    SELECT 100
    GO
    INSERT INTO S_TEST.T_TEST_TST(VAL)
    SELECT 100
    GO
    INSERT INTO S_TEST.T_TEST_TST(VAL)
    SELECT 100
    GO
     
    INSERT INTO S_TEST.T_TEST_TST(VAL)
    SELECT 10
    GO
     
    SELECT * FROM S_TEST.T_TEST_TST
    Les lignes du résultat vont avoir les identifiants 1, 2, 3 et 6. A côté de cela, on a bien sûr les messages d'erreur adéquats (2 fois en l'occurence) :
    The INSERT statement conflicted with the CHECK constraint "CK_SUM_VAL_LOWER_THAN_1000". The conflict occurred in database "INNO_ADMIN", table "S_TEST.T_TEST_TST".
    Ma question précise est : Comment faire, dans une application (.NET), lorsqu'un ordre sql d'insertion rencontre une erreur du même genre, pour connaître les identifiants qui ont été utilisés ?
    Y a-t-il une variable spéciale ou une fonction système qui permettrait de savoir cela ?? Google ne m'est pas d'une grande aide sur ce coup-là

    N.B. : Pour mon problème réel, les ordres d'insertion n'ajouteront jamais qu'une seule ligne dans la table mais autant généralisé à des ensembles si possible.

  2. #2
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    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 170
    Points : 7 422
    Points
    7 422
    Billets dans le blog
    1
    Par défaut
    J'aurais tendance à t'orienter vers des directions différentes :
    - Ne pas gérer l'ID comme un IDENTITY, mais l'alimenter par un trigger qui interroge une séquence (mais j'ai peu que la contrainte ne soit vérifiée qu'après le trigger INSTEAD OF)
    - Interdit INSERT sur la table, et passer par une requête qui fait LOCK exclusif de la table, vérifie que la nouvelle ligne pète pas la contrainte, puis fait l'insertion avant de relâcher le LOCK

  3. #3
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 339
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 339
    Points : 39 735
    Points
    39 735
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    - Interdit INSERT sur la table, et passer par une requête qui fait LOCK exclusif de la table, vérifie que la nouvelle ligne pète pas la contrainte, puis fait l'insertion avant de relâcher le LOCK
    C'est quand même un peu trop radical aucune transaction concurrente n'est possible

    Reste la solution d'une table de chrono, à comiter en même temps que la table S_TEST.T_TEST_TST

Discussions similaires

  1. Réponses: 2
    Dernier message: 22/10/2014, 15h18
  2. Afficher les pseudos qui ne commencent pas par une lettre.
    Par asoka13 dans le forum Langage SQL
    Réponses: 3
    Dernier message: 09/07/2007, 17h30
  3. Réponses: 1
    Dernier message: 09/10/2006, 21h31
  4. Selectionner les date qui ont minimum une heure d'ecart
    Par uraxyd dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 26/07/2005, 13h39

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