Mettre à jour les lignes existantes avec le numéro de séquence / caractère ou toutes les données uniques

13

J'ai ajouté une nouvelle colonne dans le tableau X

Cette colonne "cn" doit être unique et obligatoire, mais les anciennes données n'ont aucune valeur.

Comment mettre à jour les enregistrements existants avec des données uniques séquentielles ou aléatoires?

Je vous remercie.

med_alpa
la source

Réponses:

11

Même si je pense que vous avez déjà créé la colonne, dans cette réponse, je pars du principe que la colonne n'existe pas encore. IMO, une colonne obligatoire unique ne doit jamais être ajoutée sans planifier comment remplir les lignes existantes en premier. Par conséquent, je fournirai les méthodes pour le faire à partir de zéro.


La façon dont vous procédez dépend de ce qui est impliqué dans le remplissage des valeurs.

Après la méthode que vous utilisez, ajoutez une contrainte unique sur la colonne pour garantir l'intégrité des données. Pour les méthodes 1 et 2, cela peut être fait dans l'instruction unique ou dans une transaction utilisateur (non illustrée), et doit être fait dans la transaction utilisateur dans la méthode 3.

Il existe probablement quelques autres façons obscures de le faire, mais je pense que j'ai couvert les plus courantes.


Méthode 1: ajouter une colonne IDENTITY

ALTER TABLE MyTable ADD MyColumn int IDENTITY(1, 2) NOT NULL

Cela remplira toutes les lignes du tableau avec des valeurs entières commençant par la valeur de départ (1), augmentant de la valeur d'incrément (2) pour chaque ligne. Je crois que l'ordre dans lequel les valeurs sont renseignées n'est pas défini (si vous devez spécifier un ordre, utilisez la méthode 3).


Méthode 2: remplir en utilisant une contrainte par défaut

ALTER TABLE MyTable ADD MyColumn uniqueidentifier NOT NULL
    CONSTRAINT DF_MyTable_MyColumn
        DEFAULT (NEWSEQUENTIALID())

Cela fera trois choses atomiquement: 1. Ajoutez une colonne qui n'autorise pas les NULLvaleurs; 2. Créez une contrainte par défaut pour la colonne; 3. Remplissez chaque ligne du tableau à l'aide de la contrainte par défaut.

Bien que cet exemple utilise une uniqueidentifiercolonne, il fonctionne aussi bien avec n'importe quel type de données et contrainte par défaut.


Méthode 3: remplir à l'aide d'une instruction UPDATE

Ce cas se produirait lorsque, par exemple, une valeur d'une autre partie de votre application doit être ajoutée à la table, ou si vous devez spécifier un ordre exact pour les valeurs uniques.

BEGIN TRANSACTION

    ALTER TABLE MyTable ADD MyColumn int NULL

    UPDATE MyTable
        SET MyColumn = ...

    ALTER TABLE MyTable ALTER COLUMN MyColumn int NOT NULL

COMMIT TRANSACTION

Méthode 4: remplir à l'aide d'un objet SEQUENCE

Pour SQL Server 2012, vous pouvez remplir une colonne en utilisant des valeurs générées par un SEQUENCEobjet - je n'ai pas encore travaillé avec cela, donc je vais me référer à un article MSDN pour être complet.

Jon Seigel
la source
Merci à tous, j'ai utilisé la méthode 3 avec une combinaison avec la première réponse: mettre à jour T set cn = rn from (select cn, row_number () over (order by (select 1)) as rn from TableX) T
med_alpa
Exemple d'utilisation de séquence (en supposant que vous ayez une séquence appelée mysequence):update mytable set mycolumn = next value for mysequence where mycolumn is null;
Endy Tjahjono
14

Si vous êtes satisfait d'un numéro à partir de 1, vous pouvez l'utiliser row_number().

update T
set cn = rn
from (
       select cn,
              row_number() over(order by (select 1)) as rn
       from TableX
     ) T
Mikael Eriksson
la source
0

essayez ceci pour mettre à jour en utilisant une séquence ... Vous devez faire le TOP à cause de la clause order by dans l'instruction update. J'ai utilisé cette déclaration sur SQL SERVER 2012

update invoice set RecNo = (next value for seq_invoice_recno)
where invoiceid in (select top 100000 invoiceid from invoice where RecNo is null 
order by invoiceId)
hewstone
la source
-1

Et si tout cela ne fonctionne toujours pas (peut-être parce que c'est du SQL-92 ancien), vous pouvez le décomposer en plusieurs étapes, comme suggéré par Ziggy Crueltyfree Zeitgeister, ici .

CREATE TABLE sorting (sid numeric(10,10), rn int);

INSERT INTO sorting (sid, rn)
SELECT SortID, RecordNumber FROM Beleg
WHERE Year ( Valuta ) = 2016
AND Ursprungskonto = 1210
ORDER BY SortID;

UPDATE Beleg SET SortID = (SELECT rn FROM sorting WHERE sid=Beleg.SortID)
WHERE Year ( Valuta ) = 2016
AND Ursprungskonto = 1210;

DROP TABLE sorting;
Gary Czychi
la source
Qu'est-ce que c'est RecordNumber? On dirait une fonction / fonctionnalité propriétaire de Filemaker. Ne s'applique pas à SQL Server et non à la norme SQL 92.
ypercubeᵀᴹ
Oui tu as raison. RecordNumber est une colonne calculée que vous pouvez définir dans Filemaker, qui contient le numéro d'enregistrement de chaque ligne lorsqu'elle est affichée à l'écran et après qu'elle est triée (par Filemaker).
Gary Czychi
OK, bien, je ne savais pas ça. Mais la question ici n'est pas étiquetée, Filemakerdonc je ne pense pas que la réponse soit pertinente. Vous pouvez cependant utiliser une table temporaire et remplir cette colonne de ROW_NUMBER()fonction.
ypercubeᵀᴹ