2009-07-02 7 views
2

Je souhaite autoriser les utilisateurs de mon application à définir un certain nombre d'adresses e-mail (par exemple). Ensuite, je voudrais leur donner la possibilité de réorganiser ces adresses, donc l'adresse principale est en haut, secondaire suivante, etc.Champ de base de données de séquence et requête de mise à jour de l'ordre de tri

Supposons que j'ai une table UserEmailAddresses dans une base de données qui relie un utilisateur (UserId) et un adresse e-mail (EmailAddressId).

1) Quel type de données (int, float, etc.) dois-je utiliser pour le champ qui contiendra la séquence dans laquelle ces adresses e-mail seront triées?

2) Quelle requête serait efficace pour modifier ces numéros de séquence lorsque l'utilisateur réorganise ses positions? Doit-il modifier plusieurs enregistrements?

(j'utilise C# et Linq, mais psuedo-code welcome).

Répondre

3

Vous devrez ajouter un champ d'entier qui stocke l'ordre de tri des adresses électroniques.

Lorsque de nouvelles adresses électroniques sont ajoutées, elles reçoivent l'ID de tri suivant. Si une adresse doit être triée au-dessus d'une adresse existante, j'utiliserais une instruction de mise à jour pour mettre à jour toutes les adresses électroniques avec des identifiants de tri supérieurs à l'index de tri souhaité, puis mettre à jour l'adresse courriel réorganisée.

Table Schema 
----------------------- 
EmailID INT primary Key //Auto increment 
EmailAddress Varchar(N) 
SortOrderIdx INT //This would control your display order 
UserID INT //This would be the owner of this particular email list 

Email Create Statement 
----------------------- 
SELECT @NewSortOrdrIdx = MAX(SortOrderIdx)+1 
FROM EmailTable 
WHERE UserId = @UserID 

INSERT INTO EmailTable (EmailAddress, SortOrderIdx, UserID) 
VALUES (@EmailAddress, @NewSortOrdrIdx, @UserID) 

Email Reorder Statement 
----------------------- 
UPDATE EmailTable 
SET SortOrderIdx = SortOrderIdx + 1 
WHERE SortOrderIdx >= @desired_Sort_Order_Idx AND UserID = @UserID 

UPDATE EmailTable 
SET SortOrderIdx = @desired_Sort_Order_Idx 
WHERE EmailID = @resorted_Email_ID AND UserID = @UserID 

Email Select Statement 
----------------------- 
SELECT EmailAddress 
FROM EmailTable 
WHERE UserID = @UserID 
ORDER BY SortOrderIdx ASC 
+0

Je suppose que je vais devoir interroger le plus grand nombre de séquence avant d'ajouter une nouvelle adresse trop . Il semble que je sors de la base de données de cette manière ... est-ce juste le prix de cette fonctionnalité? – Feckmore

1

Voici une conception simple, qui simplifie la manipulation des "collisions". Vous ne devez mettre à jour une ligne pour que cette méthode fonctionne:

UserEmailAddresses Table 
------------------------ 
YourPKHere  <whatever you have, identity?> 
UserId   <whatever you have> 
EmailAddressId <whatever you have> 
DisplaySeq  INT 
LastChgDate  datetime 


SELECT * FROM UserEmailAddresses ORDER BY DisplaySeq ASC, LastChgDate DESC 

EDIT exemple de code

DECLARE @UserEmailAddresses table 
(
    YourPKHere  int identity(1,1) primary key 
    ,UserId   int 
    ,EmailAddressId varchar(100) 
    ,DisplaySeq  INT 
    ,LastChgDate  datetime 
) 

--existing data 
INSERT INTO @UserEmailAddresses values (1,'[email protected]',1,'1/1/2009') 
INSERT INTO @UserEmailAddresses values (1,'[email protected]',2,'2/2/2009') 
INSERT INTO @UserEmailAddresses values (1,'[email protected]',3,'3/3/2009') 
INSERT INTO @UserEmailAddresses values (2,'[email protected]',1,'1/1/2009') 
INSERT INTO @UserEmailAddresses values (2,'[email protected]',2,'2/2/2009') 

--application updates one row, no locking or blocking 
update @UserEmailAddresses set DisplaySeq=1,LastChgDate=getdate() where UserId=1 and EmailAddressId='[email protected]' --could say WHERE YourPKHere=n, but you don't give your complete table schema 


--display the emails in proper order, with displayable continuous row numbers 
SELECT 
    *, ROW_NUMBER() over(partition by UserId order by DisplaySeq ASC,LastChgDate DESC) AS ActualDuisplaySeq 
    FROM @UserEmailAddresses 
    WHERE UserId=1 

--display the e-mails in proper order 
SELECT * FROM @UserEmailAddresses Where UserId=1 ORDER BY DisplaySeq ASC, LastChgDate DESC 
+0

C'est assez intelligent ... cependant, disons que j'ai changé deux adresses donc elles sont l'adresse "supérieure", chacune avec un DisplaySeq de 1 mais avec des temps différents pour les distinguer. Maintenant, disons que je veux placer une troisième adresse à la place # 2 (entre les deux premiers) ... Je ne vois aucun moyen de le faire avec votre proposition. – Feckmore

+0

cela dépend de votre interface utilisateur. Si vous affichez une table où chaque numéro de téléphone est sur sa propre ligne et que vous les laissez entrer la valeur de tri dans une zone de texte, et qu'ils veulent avoir plusieurs valeurs dupliquées en même temps, il triera comme vous le décrivez. mais s'ils y entrent uniquement, il n'y a pas de problème. Si vous voulez que le programme répare l'ordre de séquence, vous devez toujours exécuter une mise à jour supplémentaire. –

Questions connexes