2010-12-12 22 views
1

J'ai une table 'order_item' avec order_item_id int order_id intComment re-séquence d'une colonne id après suppression d'une ligne (PAS UNE AUTO-INCREMENT)

la clé primaire est order_item_id + order_id

Donc, l'ID commande_idem n'est pas unique et l'ID commande non plus, mais la combinaison des deux colonnes est unique.

Si un client ajoute plusieurs éléments à leur ordre nous pourrions avoir une table comme celui-ci

order_item_id order_id 
------------------------ 
1    5 
2    5 
3    5 
4    5 

... et si le client supprime alors order_item_id 2 alors il y a une lacune dans la séquence. L'identifiant order_item_id est affiché pour la référence du client et utilisé lorsque nous envoyons des commandes d'achat aux fournisseurs.

Existe-t-il un moyen de réorganiser le order_item_id pour un order_id spécifique? Je l'ai essayé ce qui suit, mais continuer à obtenir une clé en double erreur et il ne cesse de changer l'identifiant du premier article trouvé à 0 non 1.

SET @i := 0; 

    UPDATE order_item 
    SET order_item_id = (@i := @i + 1) 
    WHERE order_id = 5 
ORDER BY order_id, order_item_id 

Merci pour toute aide.

+0

Vous utilisez Oracle? MySql? – ClosureCowboy

+0

Merci! En raison des affectations ": =", je suppose que Vijer utilise MySQL. Si SQL Server permet ceux-ci, je vais considérer mon esprit soufflé! – ClosureCowboy

+0

Désolé, oui MySQL – Vijer

Répondre

0

Vous ne pouvez le faire que pour les order_item_ids qui sont plus grands que celui qui vient d'être supprimé.

Première set @i := deleted_order_item_id - 1;

Et ajouter une clause where quelque chose comme where order_item_id > deleted_order_item_id et l'incrément en utilisant order_item_id = (@i := @i + 1)

+0

Modifié comme ceci et je reçois toujours une erreur de clé en double. Order_item_id est mis à 0 à chaque fois.

SET @i := 3 - 1; UPDATE order_item SET order_item_id = (@i := @i + 1) WHERE order_id = 7 AND order_item_id > 3
Vijer

+0

Je ne suis pas sûr, mais je pense que (@i: = @i + 1) renvoie un 0. Peut-être que vous ne pouvez pas le faire de cette façon? Je ne sais pas. Quelle base de données est-ce? – harithski

+0

La requête est correcte mais j'utilise SQLyog pour éditer et exécuter des requêtes avant de les incorporer dans PHP et apparemment SQLyog n'exécute pas les deux instructions ensemble donc @i n'est pas défini et n'incrémente pas. – Vijer

0

En fait, le code modifié à l'aide des suggestions de hartihski fonctionne, mais il doit y avoir un problème avec SQLyog exécuter la requête. Lorsque j'ai utilisé phpMyAdmin pour exécuter la requête, cela a fonctionné comme prévu.

+0

En fait, ce code fonctionne parfaitement dans MyPHPAdmin, mais pas dans SQLyog.SET @i: = 0; MISE À JOUR order_item SET order_item_id = (@i: = @i + 1) O WH order_id = 7 – Vijer

2

Il ne faut pas confondre les identifiants et les numéros lors de la commande, et vous n'aurez pas de problème. Ce dernier peut facilement être fait même du côté du client. C'est une très mauvaise idée de changer les clés primaires.

1

Pour ajouter à newtover commentaire de:

Modification de la clé primaire d'une ligne uniquement pour l'affichage des fins est un très mauvaise idée. Vous pouvez toujours générer le "numéro de ligne" à la volée côté client.

Si vous devez faire cela du côté de la base de données, vous pouvez le faire pendant la récupération. Pas besoin de changer la clé primaire.

Malheureusement MySQL ne supporte pas la fonction row_number(), mais cela peut être contourné en utilisant les éléments suivants "hack":

 
SELECT @rownum := @rownum + 1 as order_item_sequence, 
     o.order_item_id, 
     o.order_id, 
FROM order_table o, 
    (SELECT @rownum := 0) r 
WHERE o.order_id = 42;