Oracle SQL: Comment lire-et-incrémenter un champ
Je suis refactoring de l'importation de données de la procédure pour une application d'entreprise et suis tombé sur un extrait de j'aimerais trouver une meilleure solution. Lors de l'importation de données que nous avons à créer une entité unique pour chaque ensemble de données et il y a un compteur dans un champ à utiliser pour attribuer l'id de façon séquentielle. Vous lisez le terrain pour obtenir la prochaine free id et l'incrémenter par la suite afin de se préparer pour la prochaine fois.
Au moment où cela est fait en deux étapes dans l'application d'origine, écrit en 'C':
SELECT idnext FROM mytable;
UPDATE mytable SET idnext = idnext + 1;
Bien sûr, il est une condition de concurrence ici, si plusieurs processus de faire la même chose.
Edit: Important corequis: je ne peux pas toucher la base de données/définition d'un champ, d'une séquence.
Nous sommes réécriture en perl, et j'aimerais faire la même chose, mais en mieux. Atomique solution serait sympa. Malheureusement, mes compétences SQL sont limitées, alors je me suis tourner vers la sagesse collective 🙂
OriginalL'auteur markus_b | 2010-01-08
Vous devez vous connecter pour publier un commentaire.
Dans ce cas particulier, une séquence est la bonne solution comme mentionné. Mais si dans un avenir situation dont vous avez besoin à la fois de mettre à jour quelque chose et de retourner une valeur dans la même déclaration, vous pouvez utiliser le
RETURNING
clause:Si le code d'appel est PL/SQL, remplacer l' ? avec un local PL/SQL variable; sinon, vous pouvez lier un paramètre de sortie dans votre programme.
Edit: Depuis que vous l'avez mentionné, Perl, quelque chose comme cela devrait marcher (non testé):
Voir DBI.
Mon code d'appel est perl. J'ai essayé cela sur le sql en ligne de commande, mais il a des problèmes de syntaxe: UPDATE matable SET idnext = idnext + 1 RETOUR idnext
la partie est nécessaire. Et il ne fonctionnera pas sur une ligne de commande (pour autant que je sache).
Mise à jour de ma réponse.
Désolé pour le retard, d'autres choses ont été plus urgent... Ce beau travail pour moi avec le petit bémol que j'ai à décrémenter idnext que cette instruction renvoie la valeur après l'incrémentation et j'en ai besoin avant de s'incrémenter. Buf heureusement, un simple $idnext-- fixe. Merci !
OriginalL'auteur Dan
Pourquoi ne pas utiliser un séquence?
Créer la séquence une fois, quel que soit le DÉMARRER AVEC la valeur que vous souhaitez:
Puis dans le code de votre application au moment de l'exécution, vous pouvez utiliser cette déclaration pour obtenir la valeur suivante:
mise à Jour: en Utilisant une séquence qui serait la meilleure méthode, mais puisque vous ne pouvez pas modifier la base de données, puis je suis d'accord que l'utilisation de RETOUR devrait fonctionner pour votre situation:
OriginalL'auteur wweicker
Utiliser SELECT POUR instruction de mise à JOUR. Elle garantit des droits mutuellement exclusifs :
"SÉLECTIONNEZ
POUR METTRE À JOUR;
OriginalL'auteur Ender
Un séquence va faire le travail, jetez un oeil à par exemple Oracle séquences
OriginalL'auteur Steve De Caux