Zaktualizuj istniejące wiersze za pomocą numeru squence / char lub dowolnych unikalnych danych

13

Dodałem nową kolumnę w tabeli X.

Ta kolumna „cn” musi być unikalna i obowiązkowa, ale stare dane nie mają żadnej wartości.

Jak zaktualizować istniejące rekordy o kolejno lub losowo unikatowe dane?

Dziękuję Ci.

med_alpa
źródło

Odpowiedzi:

11

Chociaż myślę, że kolumna już została utworzona, w tej odpowiedzi zakładam, że kolumna jeszcze nie istnieje. IMO, unikalna wymagana kolumna nigdy nie powinna zostać dodana bez planowania, jak najpierw wypełnić istniejące wiersze. Dlatego przedstawię metody, aby to zrobić, zaczynając od zera.


To, jak to zrobisz, zależy od tego, co wiąże się z wypełnianiem wartości.

Po wybraniu dowolnej metody dodaj unikalne ograniczenie dla kolumny, aby zapewnić integralność danych. W przypadku metod 1 i 2 można to zrobić w ramach pojedynczego wyciągu lub transakcji użytkownika (nie pokazano) i należy to zrobić w ramach transakcji użytkownika w metodzie 3.

Prawdopodobnie istnieje kilka innych niejasnych sposobów, ale myślę, że omówiłem najczęściej.


Metoda 1: Dodaj kolumnę TOŻSAMOŚĆ

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

Spowoduje to zapełnienie wszystkich wierszy w tabeli wartościami całkowitymi rozpoczynającymi się od wartości początkowej (1), zwiększając się o wartość przyrostu (2) dla każdego wiersza. Uważam, że kolejność wypełniania wartości jest niezdefiniowana (jeśli musisz podać kolejność, użyj metody 3).


Metoda 2: Wypełnij przy użyciu domyślnego ograniczenia

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

To zrobi trzy rzeczy atomowo: 1. Dodaj kolumnę, która nie zezwala na NULLwartości; 2. Utwórz domyślne ograniczenie dla kolumny; 3. Wypełnij każdy wiersz w tabeli przy użyciu domyślnego ograniczenia.

Chociaż w tym przykładzie użyto uniqueidentifierkolumny, działa ona równie dobrze z dowolnym typem danych i domyślnym ograniczeniem.


Metoda 3: Wypełnij przy użyciu instrukcji UPDATE

Ten przypadek miałby miejsce, gdy na przykład istniała wartość z innej części aplikacji, którą należy dodać do tabeli lub trzeba podać dokładną kolejność unikalnych wartości.

BEGIN TRANSACTION

    ALTER TABLE MyTable ADD MyColumn int NULL

    UPDATE MyTable
        SET MyColumn = ...

    ALTER TABLE MyTable ALTER COLUMN MyColumn int NOT NULL

COMMIT TRANSACTION

Metoda 4: Wypełnij przy użyciu obiektu SEKWENCJA

W przypadku SQL Server 2012 można wypełnić kolumnę przy użyciu wartości wygenerowanych przez SEQUENCEobiekt - jeszcze z tym nie pracowałem, więc w celu uzyskania kompletności odwołam się do artykułu MSDN .

Jon Seigel
źródło
Dziękuję wszystkim, użyłem metody 3 z kombinacją z pierwszą odpowiedzią: aktualizacja T ustaw cn = rn od (wybierz cn, numer_wiersza () ponad (zamów według (wybierz 1)) jak rn z tabeli X) T
med_alpa
Przykład użycia sekwencji (zakładając, że masz sekwencję o nazwie mysequence):update mytable set mycolumn = next value for mysequence where mycolumn is null;
Endy
14

Jeśli jesteś zadowolony z numeru zaczynającego się od 1, możesz użyć row_number().

update T
set cn = rn
from (
       select cn,
              row_number() over(order by (select 1)) as rn
       from TableX
     ) T
Mikael Eriksson
źródło
0

spróbuj to zaktualizować za pomocą sekwencji ... Musisz zrobić TOP, ponieważ kolejność według klauzuli w instrukcji aktualizacji. Użyłem tego oświadczenia na 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
źródło
-1

A jeśli to wszystko nadal nie zadziała (może dlatego, że jest to zwykły stary SQL-92), możesz podzielić to na wiele kroków, jak sugeruje Ziggy Crueltyfree Zeitgeister tutaj .

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
źródło
Co to RecordNumberjest Wydaje się, że jest to zastrzeżona funkcja / funkcja Filemaker. Nie dotyczy SQL Server i nie jest w standardzie SQL 92.
ypercubeᵀᴹ
Tak, masz rację. RecordNumber to kolumna obliczeniowa, którą można zdefiniować w Filemaker, która przechowuje numer rekordu każdego wiersza, gdy jest wyświetlany na ekranie i po posortowaniu (według Filemaker).
Gary Czychi 20.04.16
OK, dobrze, nie wiedziałem o tym. Ale pytanie tutaj nie jest oznaczone, Filemakerwięc nie sądzę, aby odpowiedź była istotna. Możesz jednak użyć tabeli tymczasowej i wypełnić tę kolumnę ROW_NUMBER()funkcją.
ypercubeᵀᴹ