Aktualisieren Sie vorhandene Zeilen mit der Sequenznummer / dem Zeichen oder eindeutigen Daten

13

Ich habe eine neue Spalte in die Tabelle X eingefügt

Diese Spalte "cn" muss eindeutig und obligatorisch sein, aber alte Daten haben keinen Wert.

Wie aktualisiere ich die vorhandenen Datensätze mit sequenziellen oder zufälligen eindeutigen Daten?

Vielen Dank.

med_alpa
quelle

Antworten:

11

Obwohl ich denke, dass Sie die Spalte bereits erstellt haben, gehe ich in dieser Antwort davon aus, dass die Spalte noch nicht vorhanden ist. IMO, eine eindeutige erforderliche Spalte sollte niemals hinzugefügt werden, ohne vorher zu planen, wie die vorhandenen Zeilen gefüllt werden sollen. Daher werde ich die Methoden bereitstellen, um dies von Null aus zu tun.


Wie Sie dies tun, hängt davon ab, was zum Auffüllen der Werte erforderlich ist.

Fügen Sie nach der von Ihnen verwendeten Methode eine eindeutige Einschränkung für die Spalte hinzu, um die Datenintegrität sicherzustellen. Für die Methoden 1 und 2 kann dies innerhalb der einzelnen Anweisung oder innerhalb einer Benutzertransaktion (nicht gezeigt) erfolgen und sollte innerhalb der Benutzertransaktion in Methode 3 erfolgen.

Es gibt wahrscheinlich ein paar andere undurchsichtige Möglichkeiten, dies zu tun, aber ich denke, ich habe die häufigsten behandelt.


Methode 1: fügen Sie eine IDENTITY-Spalte hinzu

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

Dies füllt alle Zeilen in der Tabelle mit ganzzahligen Werten, beginnend mit dem Startwert (1), und erhöht sich für jede Zeile um den Inkrementwert (2). Ich glaube, die Reihenfolge, in der die Werte ausgefüllt werden, ist undefiniert (wenn Sie eine Reihenfolge angeben müssen, wenden Sie Methode 3 an).


Methode 2: Füllen Sie mit einer Standardeinschränkung

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

Auf diese Weise werden im Prinzip drei Aktionen ausgeführt: 1. Fügen Sie eine Spalte hinzu, die keine NULLWerte zulässt . 2. Erstellen Sie eine Standardbedingung für die Spalte. 3. Füllen Sie jede Zeile in der Tabelle mit der Standardeinschränkung.

In diesem Beispiel wird zwar eine uniqueidentifierSpalte verwendet, es funktioniert jedoch genauso gut mit jedem Datentyp und jeder Standardeinschränkung.


Methode 3: Füllen Sie mit einer UPDATE-Anweisung

Dieser Fall würde auftreten, wenn beispielsweise ein Wert aus einem anderen Teil Ihrer Anwendung zur Tabelle hinzugefügt werden muss oder Sie eine genaue Reihenfolge für die eindeutigen Werte angeben müssen.

BEGIN TRANSACTION

    ALTER TABLE MyTable ADD MyColumn int NULL

    UPDATE MyTable
        SET MyColumn = ...

    ALTER TABLE MyTable ALTER COLUMN MyColumn int NOT NULL

COMMIT TRANSACTION

Methode 4: Füllen Sie mit einem SEQUENCE-Objekt

In SQL Server 2012 können Sie eine Spalte mit Werten füllen, die von einem SEQUENCEObjekt generiert wurden. Ich habe noch gar nicht damit gearbeitet, daher werde ich der Vollständigkeit halber auf einen MSDN-Artikel verweisen .

Jon Seigel
quelle
Vielen Dank, ich habe die Methode 3 mit einer Kombination mit der ersten Antwort verwendet: update T set cn = rn from (wähle cn, row_number () over (order by (wähle 1)) as rn from TableX) T
med_alpa
Beispiel für die Verwendung der Sequenz (vorausgesetzt, Sie haben eine Sequenz namens mysequence):update mytable set mycolumn = next value for mysequence where mycolumn is null;
Endy Tjahjono
14

Wenn Sie mit einer Zahl ab 1 zufrieden sind, können Sie verwenden row_number().

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

Versuchen Sie dies, um ein Update mit einer Sequenz durchzuführen ... Sie müssen TOP ausführen, da die order by-Klausel in der update-Anweisung angegeben ist. Ich habe diese Anweisung in SQL Server 2012 verwendet

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
quelle
-1

Und wenn all dies immer noch nicht funktioniert (vielleicht, weil es einfach altes SQL-92 ist), können Sie dies in mehrere Schritte aufteilen, wie von Ziggy Crueltyfree Zeitgeister hier vorgeschlagen .

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
quelle
Was ist das RecordNumber? Scheint eine proprietäre Filemaker-Funktion zu sein. Gilt nicht für SQL Server und nicht für den SQL 92-Standard.
Ypercubeᵀᴹ
Ja, du hast Recht. RecordNumber ist eine berechnete Spalte, die Sie in Filemaker definieren können. Sie enthält die Datensatznummer jeder Zeile, wenn sie auf dem Bildschirm angezeigt und danach sortiert wird (nach Filemaker).
Gary Czychi
OK, gut, wusste das nicht. Aber die Frage hier ist nicht markiert, Filemakerdaher halte ich die Antwort nicht für relevant. Sie könnten jedoch eine temporäre Tabelle verwenden und diese Spalte mit ROW_NUMBER()Funktion füllen .
Ypercubeᵀᴹ