Comment puis-je enregistrer des modifications dans une liste séquentielle de noms dans la base de données SQL?

StackOverflow https://stackoverflow.com/questions/4971542

Question

Ok, voici le scénario. Je pense que c'est assez courant, et je l'ai résolu dans une vie antérieure en utilisant une approche brute-force, mais je pense qu'il doit y avoir une meilleure façon.

Compte tenu d'une liste commandée de noms et d'une interface utilisateur où l'utilisateur peut réorganiser, supprimer, modifier et ajouter des noms à la liste, comment metteriez-vous à jour la liste stockée dans une base de données SQL?

Voici la définition du tableau:

CREATE TABLE [dbo].[AssyLines](
  [AssyLineID] [int] IDENTITY(1,1) NOT NULL,
  [ShortName] [varchar](16) NOT NULL,
  [LongName] [varchar](45) NOT NULL,
  [Seq] [tinyint] NOT NULL,
CONSTRAINT [PK_AssyLines] PRIMARY KEY CLUSTERED 

Ce que je veux faire, c'est lire toutes les entrées de la table et les afficher dans l'ordre SEQ dans l'interface utilisateur. L'utilisateur peut ensuite modifier Shortname ou LongName, réorganiser la liste, ajouter de nouvelles entrées ou supprimer les entrées existantes, puis enregistrer la liste modifiée dans la base de données.

Il s'agit d'une application client-serveur, si cela fait une différence. Le service WCF gère l'interaction de la base de données, le client expédie simplement un tableau d'enregistrements vers et depuis le service.

Mon approche de force brute consiste à verrouiller le tableau, à supprimer toutes les entrées, puis à réécrire les nouveaux enregistrements à la table - le tout dans une transaction, bien sûr, en utilisant une procédure stockée et une variable de table ou une table temporaire. Brut mais efficace, mais je ne peux pas m'empêcher de sentir qu'il existe une façon assez standard de le faire sans nuker la table et la recréer chaque fois que quelqu'un fait une modification mineure.

Des idées? J'ai 4 ou 5 listes de ce type dans l'application sur laquelle je travaille actuellement.

Merci, Dave

Était-ce utile?

La solution

Pourquoi ne pas simplement exécuter une requête de mise à jour pour chaque enregistrement (identifié par AssylineId, qui ne devrait pas changer) qui met à jour les autres colonnes de ce que l'utilisateur a spécifié? Pas besoin de supprimer quoi que ce soit, et vous pouvez réduire la quantité d'opérations DB en gardant une trace de ce que l'utilisateur a changé.

Si vous craignez de réorganiser le Seq Partie, je pense que cela fonctionnera pour cela:

if (newSeq < oldSeq)
{
    sql = "UPDATE AssyLines SET Seq = Seq + 1 WHERE Seq >= @seq AND Seq < @oldSeq AND AssyLineID <> @lineID";
}
else if (newSeq > oldSeq)
{
    sql = "UPDATE AssyLines SET Seq = Seq - 1 WHERE Seq <= @seq AND Seq > @oldSeq AND AssyLineID <> @lineID";
}

Peut-être que je ne comprends pas pourquoi vous pensez que vous avez besoin de nouer la table à chaque fois. Cela ressemble à votre fonctionnement de base de sélection de modification autre que la pièce SEQ.

Autres conseils

Je ne suis pas un développeur .NET, mais une autre façon élégante de le faire serait d'avoir 3 auditeurs sur la table; Un écouteur ADD, un écouteur de mise à jour et un écouteur supprimé. Les auditeurs déclencheraient un insert, une mise à jour et une suppression, respectivement.

Le tri de la liste n'a aucun effet sur les données stockées sur la base de données.

L'approche que j'adopterais avec cela consiste à utiliser la clé primaire pour lier les mises à jour, insérer et supprimer aux modifications, et effectuer quelques passes à travers les données.

  1. Chargez la liste à partir de la base de données dans l'interface utilisateur et stockez l'ID par rapport à l'élément. Conservez également un drapeau "modifié" qui est initialement défini sur False pour chaque élément.
  2. Apporter des modifications aux données de l'interface utilisateur comme ceci:
    • Ajouts aux données en les ajoutant, en définissant l'ID (clé primaire) à -1 et le drapeau modifié en true.
    • Mises à jour des données en les modifiant, en définissant l'indicateur modifié en true.
    • Supprime les données en les supprimant simplement.
  3. Itérer dans chaque élément de la liste où le drapeau modifié = true et effectuer ce qui suit:
    • Si id = -1, ajoutez un nouvel enregistrement en utilisant l'insert.
    • Si ID> -1, mettez à jour l'enregistrement existant correspondant à l'ID par rapport à l'enregistrement que vous souhaitez mettre à jour à l'aide d'une mise à jour.
  4. Ensuite, relisez tous les identifiants des enregistrements qui existent dans la base de données, parcourez chacun et vérifiez la liste pour voir s'il existe. Sinon, supprimez-le de la base de données à l'aide d'une suppression.

L'étape 4 pourrait devenir assez lente si vous avez beaucoup de données. Une manière légèrement différente plus efficace dépendrait s'il est possible de «marquer» un enregistrement tel que supprimé dans l'interface utilisateur et de le cacher de la vue sans le retirer. Ensuite, vous pouvez remplacer l'indicateur modifié par un statut qui est défini sur «I», «U» ou «D» selon qu'il s'agit d'un insert, d'une mise à jour ou d'une suppression. Ensuite, vous n'auriez besoin qu'un seul passage par les données.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top