Aggiorna le righe esistenti con il numero / carattere squence o qualsiasi dato univoco


13

Ho aggiunto una nuova colonna nella tabella X

Questa colonna "cn" deve essere unica e obbligatoria, ma i vecchi dati non hanno alcun valore.

Come aggiornare i record esistenti con dati univoci sequenziali o casuali?

Grazie.

Risposte:


11

Anche se penso che tu abbia già creato la colonna, in questa risposta suppongo che la colonna non esista ancora. IMO, una colonna obbligatoria univoca non dovrebbe mai essere aggiunta senza pianificare prima come popolare le righe esistenti. Pertanto, fornirò i metodi per farlo a partire da zero.


Come lo fai dipende da cosa è coinvolto nella compilazione dei valori.

Dopo qualunque metodo si usi, aggiungere un vincolo univoco sulla colonna per garantire l'integrità dei dati. Per i metodi 1 e 2, questo può essere fatto all'interno della singola istruzione o all'interno di una transazione dell'utente (non mostrata) e dovrebbe essere fatto all'interno della transazione dell'utente nel metodo 3.

Probabilmente ci sono alcuni altri modi oscuri per farlo, ma penso di aver coperto il più comune.


Metodo 1: aggiungere una colonna IDENTITY

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

Questo popolerà tutte le righe della tabella con valori interi che iniziano con il valore seed (1), aumentando del valore di incremento (2) per ogni riga. Credo che l'ordine in cui i valori vengono popolati sia indefinito (se devi specificare un ordine, usa il Metodo 3).


Metodo 2: popolare utilizzando un vincolo predefinito

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

Ciò farà atomicamente tre cose: 1. Aggiungi una colonna che non consente NULLvalori; 2. Creare un vincolo predefinito per la colonna; 3. Popolare ciascuna riga della tabella utilizzando il vincolo predefinito.

Mentre questo esempio utilizza una uniqueidentifiercolonna, funziona altrettanto bene con qualsiasi tipo di dati e vincolo predefinito.


Metodo 3: popolare utilizzando un'istruzione UPDATE

Questo caso si verifica quando, ad esempio, esiste un valore proveniente da un'altra parte dell'applicazione che deve essere aggiunto alla tabella o è necessario specificare un ordine esatto per i valori univoci.

BEGIN TRANSACTION

    ALTER TABLE MyTable ADD MyColumn int NULL

    UPDATE MyTable
        SET MyColumn = ...

    ALTER TABLE MyTable ALTER COLUMN MyColumn int NOT NULL

COMMIT TRANSACTION

Metodo 4: popolare usando un oggetto SEQUENCE

Per SQL Server 2012, puoi popolare una colonna utilizzando i valori generati da un SEQUENCEoggetto: non ho ancora lavorato con questo, quindi farò riferimento a un articolo MSDN per completezza.


Grazie a tutti, ho usato il metodo 3 con una combinazione con la prima risposta: aggiorna T imposta cn = rn da (seleziona cn, row_number () su (ordina per (seleziona 1)) come rn da TableX) T
med_alpa

Esempio di utilizzo della sequenza (supponendo che tu abbia una sequenza chiamata mysequence):update mytable set mycolumn = next value for mysequence where mycolumn is null;
Endy Tjahjono

14

Se sei soddisfatto di un numero a partire da 1 puoi usare row_number().

update T
set cn = rn
from (
       select cn,
              row_number() over(order by (select 1)) as rn
       from TableX
     ) T


0

prova questo per aggiornare usando una sequenza ... Devi fare il TOP a causa della clausola order by nell'istruzione update. Ho usato questa affermazione su 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)

-1

E se tutto ciò non funzionerà ancora (forse perché è semplicemente il vecchio SQL-92), puoi suddividerlo in più passaggi, come suggerito da Ziggy Crueltyfree Zeitgeister, qui .

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;

Che cos'è questo RecordNumber? Sembra una funzione / caratteristica proprietaria di Filemaker. Non si applica a SQL Server e non allo standard SQL 92.
ypercubeᵀᴹ

Sì hai ragione. RecordNumber è una colonna calcolata che è possibile definire in Filemaker, che contiene il numero di record di ogni riga quando viene visualizzato sullo schermo e dopo che è stato ordinato (da Filemaker).
Gary Czychi,

OK, bene, non lo sapevo. Ma la domanda qui non è taggata, Filemakerquindi non credo che la risposta sia pertinente. Puoi usare una tabella temporanea e riempire quella colonna con la ROW_NUMBER()funzione però.
ypercubeᵀᴹ
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.