poniedziałek, 12 marca 2018

[PL] O właściwości IDENTITY w SQL Server 2014 SP2

Jeżeli podczas tworzenia tabeli w bazie danych określimy dla niej właściwość identity, to podczas wprowadzania danych do tabeli, wartość dla wiersza w tej kolumnie przyjmie narastającą wartość. Wartości w kolumnie z włączoną właściwością identity narastają co określoną wartość (określoną jako druga w nawiasie), zaczynając od wartości podanej jako pierwsza w nawiasie. Na przykład w poniższym przykładzie kolumna id będzie przyjmować wartości od 115 wzrastając o 20, czyli pierwszy wiersz otrzyma wartość 115, drugi 135, trzeci 155 itd.

USE tempdb;
go

CREATE TABLE [dbo].[test27072017] (

id int not null identity (115,20),
kolumna2 NVARCHAR(15),
kolumna3 NVARCHAR(15)
)

Dodajmy zatem kilka wierszy do utworzonej przed chwilą tabeli i sprawdźmy wynik

INSERT INTO [dbo].[test27072017] (kolumna2, kolumna3) VALUES (N'test1', N'test2');
INSERT INTO [dbo].[test27072017] (kolumna2, kolumna3) VALUES (N'test3', N'test4');
SELECT * FROM [dbo].[test27072017]

Jak widzimy pierwszy wiersz otrzymał wartość 115, kolejny 135.


Jeżeli chcielibyśmy przypisać wartość dla kolumny id z właściwością identity samodzielnie, otrzymamy błąd.

INSERT INTO [dbo].[test27072017] (id, kolumna2, kolumna3) VALUES (12, N'test3', N'test4');


Jeżeli chcielibyśmy umożliwić taką operację, należy włączyć opcję IDENTITY_INSERT w odniesieniu do bazy danych.

SET IDENTITY_INSERT [dbo].[test27072017] ON;

I wówczas system pozwoli na wprowadzenie do tabeli własnej wartości dla kolumny z właściwością identity.



Aby z powrotem wyłączyć taką możliwość, należy skorzystać z polecenia:

SET IDENTITY_INSERT [dbo].[test27072017] OFF;

Aby określić wartość generatora dla pola IDENTITY w konkretnej tabeli możemy skorzystać z następującego polecenia:
DBCC CHECKIDENT('dbo.tabela', RESEED, 400);
W powyższym przykładzie dla tabeli o nazwie 'tabela' znajdującej się w schemacie 'dbo' zostanie ustawiona wartość generatora 400 dla pola typu identity.

Aby sprawdzić aktualną wartość pola typy identity w konkretnej tabeli należy użyć polecenia: 
SELECT IDENT_CURRENT('dbo.tabela') AS [IDENT_CURRENT];

1 komentarz:

  1. W tym temacie jest jeszcze jedna ważna rzecz, o której warto wiedzieć w niestandardowych przypadkach.
    - rollback transakcji nie cofa wygenerowanej wartości, innymi słowy nie dostaniemy drugi raz takiej samej
    - nagłe wyłączenie serwera sql (np ubicie procesu, ale również wypięcie dysków, awaria prądu) może podbić identity o duży rząd wartości i nie będzie to błąd. Tu polecam poczytać jak działa mechanizm cache w identity i jak działa opcja NOCACHE w starych wersjach bazy, a jak IDENTITY_CACHE w 2017+ :>

    Na koniec przypadek wyjątkowo perfidny i odległy, bo w Microsoft Azure Data Warehouse, który bazuje częściowo na architekturze 2012 i Microsoft PDW. Tam również (od ponad roku) istnieje implementacja IDENTITY, ale tak specyficzna, że kolejno nadawane wartości nie są widoczne jako ciągły zbiór. Ma to związek z architekturą rozproszoną serwera SQL, ale w praktyce działa tak, że choć identity = (1,1) , to kolejno dwa dodane rekordy mogą mieć numery 1 i 61 w zależności od klucz dystrybucji :> Ale to temat na inną okazję ;) Polecam jednak poczytać trochę o SQL Server MPP Architecture, bo to gruuba ciekawostka!

    Pozdrawiam.
    Michał Pawlikowski

    OdpowiedzUsuń