2010-06-30 13 views
0

Pourriez-vous s'il vous plaît aidez-moi avec celui-ci:SQL stocké proc - aidez-moi à écrire celui-ci, s'il vous plaît!

Dans un de mes scripts j'insère des données dans quelque tableau "Item". L'une des colonnes du tableau "Item" est "ItemNumber". Je veux être en mesure d'appeler une fonction (très probablement un proc Stored) où il me renvoie un nombre numérique que je peux utiliser pour ItemNumber.

JE NE PEUX PAS utiliser AutoIncrement parce ItemNumber est unique et il pourrait y avoir une collision quand dans un script differnt j'insérer des données dans « Item », qui a déjà « ItemNumber »

Je ne connais que le Max numéro pour le "ItemNumber" et je suis libre d'utiliser quoi que ce soit après cela.

J'ai besoin d'une table pour ce storedProc pour stocker le prochain numéro à utiliser, non?

Je pensais à la création d'une table d'une colonne avec le nb_max_lignes_résultats en elle et un storedproc où il me retourner le nb_max_lignes_résultats et aussi augmenter le nb_max_lignes_résultats de 1 pour la prochaine utilisation

J'ai besoin d'aide pour écrire la proc stocké et l'utilisation avec l'appel INSERT INTO Item.

EDIT:

Fondamentalement, je suis des données à partir de 5 à détourner les anciennes tables où ItemNumber est soit NULL ou défini. Pour ceux qui sont définis, ils sont tous des nombres uniques. Pour les données où le ItemNumber est NULL je veux l'assigner, quelle est la meilleure approche?

Aidez s'il vous plaît!

Merci,

Voodoo

+0

S'il vous plaît essayer de rendre ce plus lisible si vous attendez de bonnes réponses. Il est très difficile de suivre votre fil de pensée –

+1

L'insertion d'une ligne à partir d'un script différent n'entraîne pas de collisions avec un ID auto-incrémenté. Les ID sont générés sur le serveur, pas par votre script. Utilisez-vous plusieurs bases de données ou tables? –

+0

@Tom H: Oui, j'utilise plusieurs tables et les insère dans une table, certaines des rowdata ont ItemNumber et d'autres sont nulles. La nouvelle table de données exige qu'ils soient Non Null et Unique sur ItemNumber. – VoodooChild

Répondre

2

(En supposant SQL Server - applique probablement la plupart des implémentations SQL)

Si vous utilisez contrainte d'identité sur votre champ, le serveur ne permettra pas qu'il y ait des cas en double . Comme l'un des commentaires notes, la valeur est calculée sur le serveur dans ce cas, et votre application ne le fournit pas (et dans des circonstances normales ne peuvent pas). Notez que le serveur ne garantit pas que les numéros seront contigus - si vous effectuez une insertion et annulez la transaction, la valeur qui aurait été utilisée serait 'perdue' - le serveur ne l'offrira plus.

Si vous avez besoin d'avoir des numéros d'identification contigus, vous devrez avoir un accès sérialisé pour mettre à jour la table, que vous auriez besoin de gérer et qui ne serait pas efficace. (Vous pouvez toujours déclariez être une colonne IDENTITY, mais il faut mettre identity_insert la table pour chaque mise à jour.)

supplémentaires:

Peut-être un peu bidouille, mais peut-être travailler pour un -off scénario. Avez-vous envisagé de copier les données dans une nouvelle table, où l'ID est défini, puis d'appliquer la contrainte IDENTITY et d'insérer celles avec des ID NULL (permettant au serveur de les allouer pour vous?) .

+0

Merci, une question de plus: disons qu'en utilisant IDENTITY le serveur me donne 33 à utiliser pour ItemNumber, que se passe-t-il quand j'essaie d'insérer (en utilisant Identity_Insert comme vous l'avez suggéré) qui a 33 comme ItemNumber? Cela causerait une collision et ne fonctionnerait pas. Je dois garder les ItemNumbers identiques et attribuer seulement ceux qui sont null. – VoodooChild

+1

Si vous utilisez des champs d'identité, vous ne voudriez normalement pas spécifier la valeur vous-même - le point est que vous laissiez le serveur le faire (de manière cohérente sans danger pour les threads). IDENTITY_INSERT est pour quand vous souhaitez passer outre la serveur pour une très bonne raison, et ne devrait pas être une opération normale. (Nous l'utilisons pour une table spécifique, où les valeurs doivent correspondre à un autre champ identy pour des raisons techniques, et la réparation manuelle occasionnelle des données - très exceptionnellement les cas exceptionnels.) – Ragster

+0

(suite) Cependant - si vous avez des données existantes dans Dans la table, vous pouvez appliquer la contrainte avec NOCHECK et appliquer uniquement la règle aux nouvelles insertions. Vous pouvez modifier manuellement ceux qui existent déjà (dans les règles du champ.) Le serveur n'insèrera jamais un numéro déjà existant pour un champ d'identité. Il ne vous «donne» pas le numéro à insérer - vous demandez l'insertion d'un enregistrement et il le fait, générant le numéro pour vous. Vous pouvez alors lui demander quelle a été la dernière identité insérée. – Ragster