Wstawianie wierszy do tabeli zawierającej tylko jedną kolumnę IDENTITY


83

Mam administratora tabeli z tylko jedną kolumną, adminId, która jest kluczem podstawowym. Ze względu na reguły biznesowe musi tak być.

Chciałbym raz na zawsze zrozumieć, w jaki sposób mogę pisać procedury składowane, które wstawiają wartości w takich tabelach. Używam SQL Server i T-SQL i próbowałem użyć SCOPE_IDENTITY (), ale to nie działa, ponieważ tabela ma wartość INSERT_IDENTITY na false lub off.

Naprawdę nie chciałbym wstawiać wartości fikcyjnej tylko po to, aby móc wstawić nowy wiersz. Dzięki!


1
Dla wyjaśnienia: Twoje pytanie brzmi „jak wstawić wiersze do tabeli programu SQL Server z pojedynczą kolumną IDENTITY”?
— gbn

Tak, masz rację, dziękuję za wyjaśnienie
— Phil

2
W przypadku osób lądujących tutaj zostało to wcześniej zadane, a prawidłowa odpowiedź jest tutaj: stackoverflow.com/questions/850327/…
— BJury,

Odpowiedzi:


140

Jeśli masz jedną kolumnę, która jest TOŻSAMOŚCIĄ, po prostu zrób to

INSERT MyTable DEFAULT VALUES;  --allows no column list. The default will be the IDENTITY
SELECT SCOPE_IDENTITY();

Jeśli nie masz tożsamości, czy możesz ją ustawić? To jest najlepszy sposób ... i użyj powyższego kodu SQL.

Jeśli nie, chcesz wstawić nowy wiersz

INSERT MyTable (admidid)
OUTPUT INSERTED.admidid --returns result to caller
SELECT ISNULL(MAX(admidid), 0) + 1 FROM MyTable

Uwagi:

  • Przy dużych obciążeniach rozwiązanie MAX może zawieść z duplikatami
  • SCOPE_IDENTITY jest po fakcie, a nie wcześniej
  • SCOPE_IDENTITY działa tylko z kolumną IDENTITY. Podobnie jak każdy idiotyzm przy użyciu IDENT_CURRENT
  • Klauzula wyjściowa zastępuje SCOPE_IDENTITY dla rozwiązania MAX

1

Musisz dodać IDENTITY_INSERT do wybranej instrukcji:

SET IDENTITY_INSERT MyTable ON

INSERT INTO MyTable
(AdminCol)

SELECT AdminColValue

 FROM Tableb

Kiedy skończysz, pamiętaj o tym

SET IDENTITY_INSERT MyTable OFF

Oto dobry opis tego, jak to działa w BOL: http://msdn.microsoft.com/en-us/library/aa259221(SQL.80).aspx


Czy mam to zrobić w ten sposób: USTAWIĆ Administratora IDENTITY_INSERT ON WSTAW DO Administratora (SCOPE_IDENTITY ()) WYŁĄCZYĆ Administratora IDENTITY_INSERT?
— Phil

Tak. To wszystko, co musisz zrobić. Ustaw na, napisz swój kod, WYŁĄCZ na końcu.
— DataWriter

Myślę, że to nie jest właściwa odpowiedź. Jeśli jest to kolumna tożsamości, nie powinieneś dodawać do niej wartości. Zaakceptowana odpowiedź jest poprawną odpowiedzią.
— Mmm

0

@Phil: Czy nie masz na myśli, że twoja tabela ma dwie (2) kolumny, kolumnę PK z automatyczną inkrementacją i kolumnę AdminName? Jeśli ma tylko jedną kolumnę, w której znajduje się AdminName, AdminName jest PK i oczywiście nie można automatycznie zwiększać ciągu. Czy reguły biznesowe wymagają, aby w pełni kwalifikowana nazwa użytkownika systemu Windows była kluczem podstawowym? Byłoby to wykonalne i sensowne, ponieważ wtedy nie byłby potrzebny alternatywny unikalny indeks w kolumnie AdminName.

Ale jeśli twoja tabela ma dwie kolumny, a nie jedną:

W SQLServer autoincrement jest częścią definicji tabeli / kolumny. Definiujesz kolumnę jako liczbę całkowitą, a następnie ustawiasz ją jako kolumnę tożsamości, określając przyrost, zwykle 1, ale może to być 2, 5 lub 10 lub cokolwiek. Aby wstawić wiersz, wystarczy wstawić inne wartości kolumn i nic nie robić z kolumną PK:

insert into T
(foo)   -- column(s) list
values('bar') -- values list

Twój zapisany proces, który wykonuje wstawianie, może uczynić SCOPE_IDENTITY wartością RETURN lub SCOPE_IDENTITY może zostać przekazany klientowi jako parametr OUT.

PS SCOPE_IDENTITY () zwraca ostatnio wygenerowaną wartość tożsamości automatycznie inkrementowaną w bieżącym zakresie; nie generuje następnej wartości tożsamości.

EDYTOWAĆ:

Przypuszczalnie twoja tabela Administratorzy zawiera zestaw administratorów. Ale jeśli nie ma żadnych kolumn poza kolumną klucza podstawowego w postaci liczby całkowitej, nie ma możliwości zidentyfikowania administratorów; jedyne, co możesz zrobić, to odróżnić je od siebie. To wcale nie prowadzi zbyt daleko. Ale jeśli twoja tabela administratora miała jedną z następujących struktur:

ID   INTEGER PRIMARY KEY AUTOINCREMENT
windowsusername   varchar(50)  (unique index)

LUB

windowsusername varchar(50) primary key

mógłbyś odwołać się do tabeli Administratora z innych tabel, a klucze obce byłyby ZNACZNE. I właśnie tego brakuje tabeli składającej się z jednej kolumny całkowitej - czyli.

Mając dwie kolumny, możesz wtedy wykonać procedurę składowaną:

insert into Administrators
(windowsusername)
values('mydomain\someusername');
return SCOPE_IDENTITY();

a program-klient odzyskałby jako wartość zwracaną automatycznie zwiększany identyfikator, który został wygenerowany automatycznie i przypisany do nowo wstawionego wiersza. Takie podejście jest zwykłą praktyką i posunąłbym się nawet do stwierdzenia, że ​​jest uważane za „najlepszą praktykę”.

PS Wspomniałeś, że nie wiedziałeś, jak „wstawić wartość”, jeśli „nie masz nic do wstawienia”. Jest w tym sprzeczność. Jeśli nie masz nic do wstawienia, po co wstawiać? Dlaczego miałbyś tworzyć, powiedzmy, nowy rekord KLIENT, jeśli nie wiesz absolutnie nic o kliencie? Nie imię, nazwisko, miasto, numer telefonu, nic?


2
Moja tabela ma JEDNĄ kolumnę, adminId, która jest przyrostową wartością int
— Phil

To najdziwniejszy projekt, jaki kiedykolwiek widziałem, a jestem w branży od ponad 20 lat i widziałem dziwne rzeczy w ciągu moich dni. Więc twoje pytanie brzmi: jak wstawić do tabeli, która zawiera tylko kolumnę klucza podstawowego zdefiniowaną jako kolumna tożsamości z autoinkrementacją, kiedy tabela zawiera tę kolumnę PK i tylko tę kolumnę PK, żadnych innych kolumn ..
— Tim

Więc po co głos przeciw? Błąd merytoryczny gdzieś czy za wyrażenie opinii o braku merytorycznego projektu?
— Tim,

1
Tylko po to, by wyjaśnić powody stojące za projektem DB. Mamy użytkowników w jednej tabeli. Jeśli istnieje związek między użytkownikami i administratorami; są traktowani jak administratorzy. W tabeli administracyjnej nie ma nic więcej niż rzeczywisty unikalny identyfikator. „Rzeczywiste” dane znajdują się w tabeli użytkowników i mają związek (z sygnaturami czasowymi, kto przyznał itp.).
— Phil

1
@Phil: Więc używasz tabeli i relacji klucza obcego, aby wyrazić, co mogłaby zrobić prosta kolumna logiczna / bitowa. Możesz nie być w stanie dodać takiej kolumny bitowej do swojej tabeli i musisz wymyślić jakieś obejście. But an autoincrementing integer whose autoincrementation must be disabled is a poor solution.Wszystko, czego potrzebujesz, to tabela równoległa z relacją jeden do jednego z tabelą użytkowników iw tej tabeli utworzysz kolumnę bitową. Kiedy ta kolumna jest prawdziwa, oznacza to, że użytkownik ma-admin. Czysty. Standard. Projekt.
— Tim
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.