2010-03-16 5 views
5

J'utilise DB2 v9 sur LUW.Comment obtenir la valeur suivante qui sera utilisée sur une colonne IDENTITY

J'ai une colonne définie comme ceci:

"ID" BIGINT NOT NULL GENERATED BY DEFAULT
AS IDENTITY (START WITH 1, INCREMENT BY 1, CACHE 20,
NO MINVALUE, NO MAXVALUE, NO CYCLE, NO ORDER),

Je voudrais connaître la meilleure façon de déterminer quelle est la valeur suivante sera pour la colonne ID prochaine fois un enregistrement est inséré dans la table . Je vais utiliser cette information pour écrire un script pour faire une vérification "de santé" sur la table qu'IDENTITY est toujours intacte et que sa valeur suivante est supérieure à la valeur la plus élevée dans la colonne ID. Je ne veux pas simplement réinitialiser la valeur à l'aveuglette. Si la table ne passe pas la vérification de santé, je veux être averti afin que je puisse déterminer ce qui cause l'IDENTITY à être "wacked".

+0

Ceci est pour un test hors ligne à effectuer tant que la base de données n'est pas utilisée. Il n'y a aucun problème avec l'insertion de personnes lors de la suppression d'enregistrements pendant l'exécution du test. –

Répondre

1

Vous ne pouvez pas déterminer l'identité suivante. Même si vous pouviez courir le risque que les données ne soient pas synchronisées au moment où vous essayez de créer un nouvel enregistrement. La seule chose à faire est de créer un nouvel enregistrement et obtenir la nouvelle identité, faire votre vérification, puis mettre à jour l'enregistrement avec le reste des données.

Vous pouvez utiliser SELECT IDENT_CURRENT ('yourtablename') pour obtenir le dernier généré. Cela a la même mise en garde que celle ci-dessus. Cela fonctionne dans T-SQL, pas sûr dans la saveur DB2.

+0

Je ne pense pas que l'identité précédente fonctionnera car dans le cas d'une nouvelle charge, il se peut qu'il n'y ait pas eu d'identité précédente. À moins qu'un reseed définit également l'identité précédente? –

+0

Votre idée de créer un nouvel enregistrement pourrait fonctionner. Je ne veux pas peupler le disque cependant. Ceci est juste une vérification et n'est pas impliqué dans la création de dossiers. Je pourrais créer un nouvel enregistrement, obtenir la valeur de la colonne d'identification, puis effectuer une restauration. Est-ce que quelqu'un sait si faire une restauration fait aussi un retour en arrière sur la valeur de départ? Je préférerais ne pas avoir un incrément de valeur de graine à chaque fois que j'exécute le test. –

+0

C'est la voie à suivre. Ne vous inquiétez pas des lacunes. Même avec un entier 32 bits non signé, vous pouvez insérer 1000 lignes par seconde, 24 heures sur 24, pendant 136 ans avant de manquer. –

1

Je ne pense pas que cela fonctionnera comme prévu. Prenons le cas où une ligne est insérée, puis avant qu'une autre ligne ne soit insérée, cette ligne est supprimée. À ce stade, l'identifiant autogénéré sera (au moins) 2 supérieur à la valeur la plus élevée de la base de données ET il sera correct. Si vous pouvez garantir qu'il n'y a pas de suppressions, cela pourrait fonctionner, mais je ne suis pas sûr de l'utilisation que cela serait. Essentiellement, vous vérifiez si les opérations de base du logiciel DB fonctionnent et, si ce n'est pas le cas, qu'allez-vous faire? Changer de fournisseur?

Si le cas est que vous souhaitez simplement réanimer la colonne d'identité, faites un max (id) et reseed la colonne dans la même transaction. Vous pouvez être sûr qu'aucun nouvel enregistrement n'est inséré lors de la réimplantation de la colonne en appliquant des sémantiques de transaction au niveau de l'isolation sérialisable.

+0

Je ne vérifie pas si les opérations de base de DB2 fonctionnent. Un exemple de ce que je pourrais attraper est une opération de chargement mal exécutée. Je peux exécuter mon script tous les jours avant le début des affaires.Si je trouve un problème, alors je peux savoir qui/quoi changeait la table affectée et discuter de la manière correcte de charger les données. Je serai heureux d'obtenir quelques faux positifs dans le cas de données en cours de suppression. Si je reçois trop de faux positifs, je peux juste tester une plage plus grande que 1. –

+0

@Michael - donc ce que vous dites est que quelqu'un pourrait activer l'insertion d'identité, puis oubliez de ressaisir la colonne pour la placer plus haut que la dernière id ils ont inséré après? Vous pouvez tester ceci en lisant simplement la valeur max id, en faisant un insert avec des données "valides", en vérifiant si elle réussit ou échoue et en ayant un identifiant supérieur à celui que vous avez observé, puis en supprimant cette ligne - le tout dans une seule transaction. Cela introduirait quelques identifiants "vides" dans la séquence, mais détecterait le genre de problème que j'ai décrit. – tvanfosson

+0

Oui, c'est le type de problème que j'essaie de piéger. J'espère que quelqu'un a une solution qui ne créera pas d'ID vides. Ce ne serait pas la fin du monde si je finissais avec un ID vide chaque fois que je courais le script, mais idéalement, je voudrais éviter cela. –

0

Si la colonne ID est définie sur GÉNÉRÉ PAR TOUJOURS, vous ne rencontrerez aucun problème de chargement/d'importation incorrect. En outre, la fonction IDENTITY_VAL_LOCAL peut être utilisée pour obtenir la valeur d'identité.
En savoir plus sur cette fonction here

Questions connexes