Кључна реч ИДЕНТИТИ је својство у СКЛ Серверу. Када је колона табеле дефинисана са својством идентитета, њена вредност ће бити аутоматски генерисана инкрементална вредност . Ову вредност креира сервер аутоматски. Због тога не можемо ручно да унесемо вредност у колону идентитета као корисник. Дакле, ако означимо колону као идентитет, СКЛ Сервер ће је попунити на начин аутоматског повећања.
Синтакса
Следеће је синтакса која илуструје употребу својства ИДЕНТИТИ у СКЛ Серверу:
IDENTITY[(seed, increment)]
Горе наведени параметри синтаксе су објашњени у наставку:
Хајде да разумемо овај концепт кроз једноставан пример.
Претпоставимо да имамо ' Ученик ' сто, а ми желимо СтудентИД да се генерише аутоматски. Имамо почетни студентски лист 10 и желите да га повећате за 1 са сваким новим ИД-ом. У овом сценарију, следеће вредности морају бити дефинисане.
Семе: 10
Повећање: 1
CREATE TABLE Student ( StudentID INT IDENTITY(10, 1) PRIMARY KEY NOT NULL, )
НАПОМЕНА: У СКЛ Серверу је дозвољена само једна колона за идентификацију по табели.
Пример ИДЕНТИТЕТА СКЛ Сервера
Хајде да разумемо како можемо да користимо својство идентитета у табели. Својство идентитета у колони може се подесити било када се креира нова табела или након што је креирана. Овде ћемо видети оба случаја са примерима.
Својство ИДЕНТИТИ са новом табелом
Следећа изјава ће креирати нову табелу са својством идентитета у наведеној бази података:
CREATE TABLE person ( PersonID INT IDENTITY(10,1) PRIMARY KEY NOT NULL, Fullname VARCHAR(100) NOT NULL, Occupation VARCHAR(50), Gender VARCHAR(10) NOT NULL );
Затим ћемо уметнути нови ред у ову табелу са знаком ОУТПУТ клаузулу да видите аутоматски генерисани ИД особе:
INSERT INTO person(Fullname, Occupation, Gender) OUTPUT inserted.PersonID VALUES('Sara Jackson', 'HR', 'Female');
Извршавање овог упита ће приказати доњи излаз:
Овај излаз показује да је први ред уметнут са вредношћу десет у ПерсонИД колону као што је наведено у колони идентитета дефиниције табеле.
Хајде да убацимо још један ред у стол за особе као испод:
INSERT INTO person(Fullname, Occupation, Gender) OUTPUT inserted.* VALUES('Mark Boucher', 'Cricketer', 'Male'), ('Josh Phillip', 'Writer', 'Male');
Овај упит ће вратити следећи излаз:
Овај излаз показује да је други ред уметнут са вредношћу 11, а трећи ред са вредношћу 12 у колони ПерсонИД.
Својство ИДЕНТИТИ са постојећом табелом
Објаснићемо овај концепт тако што ћемо прво избрисати горњу табелу и креирати их без својства идентитета. Извршите наредбу у наставку да бисте испустили табелу:
DROP TABLE person;
Затим ћемо креирати табелу користећи следећи упит:
CREATE TABLE person ( Fullname VARCHAR(100) NOT NULL, Occupation VARCHAR(50), Gender VARCHAR(10) NOT NULL );
Ако желимо да додамо нову колону са својством идентитета у постојећу табелу, треба да користимо команду АЛТЕР. Упит у наставку ће додати ПерсонИД као колону идентитета у табели особа:
ALTER TABLE person ADD PersonID INT IDENTITY(10,1) PRIMARY KEY NOT NULL;
Експлицитно додавање вредности у колону идентитета
Ако додамо нови ред у горњу табелу тако што ћемо експлицитно навести вредност колоне идентитета, СКЛ Сервер ће приказати грешку. Погледајте доњи упит:
INSERT INTO person(Fullname, Occupation, Gender, PersonID) VALUES('Mary Smith', 'Business Analyst', 'Female', 13);
Извршавање овог упита ће довести до следеће грешке:
Да бисмо експлицитно убацили вредност колоне идентитета, морамо прво да поставимо вредност ИДЕНТИТИ_ИНСЕРТ на ОН. Затим извршите операцију уметања да бисте додали нови ред у табелу, а затим подесите вредност ИДЕНТИТИ_ИНСЕРТ на ОФФ. Погледајте скрипту кода испод:
SET IDENTITY_INSERT person ON /*INSERT VALUE*/ INSERT INTO person(Fullname, Occupation, Gender, PersonID) VALUES('Mary Smith', 'Business Analyst', 'Female', 14); SET IDENTITY_INSERT person OFF SELECT * FROM person;
ИДЕНТИТИ_ИНСЕРТ УКЉУЧЕНО омогућава корисницима да ставе податке у колоне идентитета, док ИДЕНТИТИ_ИНСЕРТ ОФФ спречава их да додају вредност овој колони.
Извршавање скрипте кода ће приказати доњи излаз где можемо видети да је ПерсонИД са вредношћу 14 успешно уметнут.
Функција ИДЕНТИТИ
СКЛ Сервер обезбеђује неке функције идентитета за рад са колонама ИДЕНТИТИ у табели. Ове функције идентитета су наведене у наставку:
- @@ИДЕНТИТИ Функција
- Функција СЦОПЕ_ИДЕНТИТИ().
- Функција ИДЕНТ_ЦУРРЕНТ
- Функција ИДЕНТИТИ
Хајде да погледамо функције ИДЕНТИТИ са неким примерима.
@@ИДЕНТИТИ Функција
@@ИДЕНТИТИ је системски дефинисана функција која приказује последњу вредност идентитета (максимална коришћена вредност идентитета) креирана у табели за колону ИДЕНТИТИ у истој сесији. Ова колона функције враћа вредност идентитета генерисану наредбом након уметања новог уноса у табелу. Враћа а НУЛА вредност када извршимо упит који не креира вредности ИДЕНТИТИ. Увек ради у оквиру тренутне сесије. Не може се користити на даљину.
Пример
Претпоставимо да је тренутна максимална вредност идентитета у табели особа 13. Сада ћемо додати један запис у истој сесији који повећава вредност идентитета за један. Затим ћемо користити функцију @@ИДЕНТИТИ да добијемо последњу вредност идентитета креирану у истој сесији.
Ево целе скрипте кода:
SELECT MAX(PersonID) AS maxidentity FROM person; INSERT INTO person(Fullname, Occupation, Gender) VALUES('Brian Lara', 'Cricket', 'Male'); SELECT @@IDENTITY;
Извршавање скрипте ће вратити следећи излаз где можемо видети да је максимална коришћена вредност идентитета 14.
Функција СЦОПЕ_ИДЕНТИТИ().
СЦОПЕ_ИДЕНТИТИ() је системски дефинисана функција за приказати најновију вредност идентитета у табели под тренутним опсегом. Овај опсег може бити модул, окидач, функција или ускладиштена процедура. Слична је функцији @@ИДЕНТИТИ(), осим што ова функција има само ограничен опсег. Функција СЦОПЕ_ИДЕНТИТИ враћа НУЛЛ ако је извршимо пре операције уметања која генерише вредност у истом опсегу.
Пример
Код у наставку користи функције @@ИДЕНТИТИ и СЦОПЕ_ИДЕНТИТИ() у истој сесији. Овај пример ће прво приказати последњу вредност идентитета, а затим уметнути један ред у табелу. Затим извршава обе функције идентитета.
SELECT MAX(PersonID) AS maxid FROM person; INSERT INTO person(Fullname, Occupation, Gender) VALUES('Jennifer Winset', 'Actoress', 'Female'); SELECT SCOPE_IDENTITY(); SELECT @@IDENTITY;
Извршавање кода ће приказати исту вредност у тренутној сесији и сличан опсег. Погледајте доњу излазну слику:
Сада ћемо видети како се обе функције разликују на примеру. Прво ћемо креирати две табеле са именом запослени_подаци и одељење користећи следећу изјаву:
CREATE TABLE employee_data ( emp_id INT IDENTITY(1, 1) PRIMARY KEY NOT NULL, fullname VARCHAR(20) NULL ) GO CREATE TABLE department ( department_id INT IDENTITY(100, 5) PRIMARY KEY, department_name VARCHAR(20) NULL );
Затим креирамо ИНСЕРТ окидач у табели емплоиее_дата. Овај окидач се позива да убаци ред у табелу одељења кад год убацимо ред у табелу запослени_подаци.
Упит у наставку креира окидач за уметање подразумеване вредности 'ТО' у табели одељења на сваком упиту за уметање у табели запослених_дата:
пд.мерге
CREATE TRIGGER Insert_Department ON employee_data FOR INSERT AS BEGIN INSERT INTO department VALUES ('IT') END;
Након креирања окидача, убацићемо један запис у табелу запослених_дата и видети излаз обе функције @@ИДЕНТИТИ и СЦОПЕ_ИДЕНТИТИ().
INSERT INTO employee_data VALUES ('John Mathew');
Извршавање упита ће додати један ред у табелу емплоиее_дата и генерисати вредност идентитета у истој сесији. Када се упит за уметање изврши у табели емплоиее_дата, он аутоматски позива окидач за додавање једног реда у табелу одељења. Почетна вредност идентитета је 1 за Емплоиее_дата и 100 за табелу одељења.
Коначно, извршавамо доле наведене изјаве које приказују излаз 100 за функцију СЕЛЕЦТ @@ИДЕНТИТИ и 1 за функцију СЦОПЕ_ИДЕНТИТИ јер враћају вредност идентитета само у истом опсегу.
SELECT MAX(emp_id) FROM employee_data SELECT MAX(department_id) FROM department SELECT @@IDENTITY SELECT SCOPE_IDENTITY()
Ево резултата:
Функција ИДЕНТ_ЦУРРЕНТ().
ИДЕНТ_ЦУРРЕНТ је системски дефинисана функција за приказати најновију вредност ИДЕНТИТИ генерисан за дату табелу под било којом везом. Ова функција не узима у обзир опсег СКЛ упита који креира вредност идентитета. Ова функција захтева име табеле за коју желимо да добијемо вредност идентитета.
Пример
Можемо то разумети тако што прво отворимо два прозора за повезивање. Убацићемо један запис у први прозор који генерише вредност идентитета 15 у табели особа. Затим можемо да проверимо ову вредност идентитета у другом прозору везе где можемо да видимо исти излаз. Ево целог кода:
1st Connection Window INSERT INTO person(Fullname, Occupation, Gender) VALUES('John Doe', 'Engineer', 'Male'); GO SELECT MAX(PersonID) AS maxid FROM person; 2nd Connection Window SELECT MAX(PersonID) AS maxid FROM person; GO SELECT IDENT_CURRENT('person') AS identity_value;
Извршавање горњих кодова у два различита прозора ће приказати исту вредност идентитета.
Функција ИДЕНТИТИ().
Функција ИДЕНТИТИ() је системски дефинисана функција користи се за уметање колоне идентитета у нову табелу . Ова функција се разликује од својства ИДЕНТИТИ које користимо са изразима ЦРЕАТЕ ТАБЛЕ и АЛТЕР ТАБЛЕ. Ову функцију можемо користити само у наредби СЕЛЕЦТ ИНТО, која се користи приликом преноса података из једне табеле у другу.
Следећа синтакса илуструје употребу ове функције у СКЛ Серверу:
IDENTITY (data_type , seed , increment) AS column_name
Ако изворна табела има колону ИДЕНТИТИ, табела формирана командом СЕЛЕЦТ ИНТО је подразумевано наслеђује. На пример , претходно смо креирали табелу особу са колоном идентитета. Претпоставимо да креирамо нову табелу која наслеђује табелу особа помоћу наредби СЕЛЕЦТ ИНТО са функцијом ИДЕНТИТИ(). У том случају добићемо грешку јер изворна табела већ има колону идентитета. Погледајте доњи упит:
SELECT IDENTITY(INT, 100, 2) AS NEW_ID, PersonID, Fullname, Occupation, Gender INTO person_info FROM person;
Извршавање горње изјаве ће вратити следећу поруку о грешци:
Хајде да направимо нову табелу без својства идентитета користећи следећу изјаву:
CREATE TABLE student_data ( roll_no INT PRIMARY KEY NOT NULL, fullname VARCHAR(20) NULL )
Затим копирајте ову табелу користећи наредбу СЕЛЕЦТ ИНТО укључујући функцију ИДЕНТИТИ на следећи начин:
SELECT IDENTITY(INT, 100, 1) AS student_id, roll_no, fullname INTO temp_data FROM student_data;
Када се наредба изврши, можемо је верификовати помоћу сп_хелп команда која приказује својства табеле.
Колона ИДЕНТИТИ можете видети у ТЕМПТАБЛЕ својства према наведеним условима.
Ако користимо ову функцију са наредбом СЕЛЕЦТ, СКЛ Сервер ће приказати следећу поруку о грешци:
Порука 177, ниво 15, стање 1, ред 2 Функција ИДЕНТИТИ се може користити само када израз СЕЛЕЦТ има клаузулу ИНТО.
Поновно коришћење вредности ИДЕНТИТИ
Не можемо поново да користимо вредности идентитета у табели СКЛ Сервера. Када избришемо било који ред из табеле колоне идентитета, у колони идентитета ће се направити празнина. Такође, СКЛ Сервер ће направити празнину када убацимо нови ред у колону идентитета, а изјава није успела или је враћена. Празнина указује да су вредности идентитета изгубљене и да се не могу поново генерисати у колону ИДЕНТИТЕТ.
Размотрите пример у наставку да бисте га практично разумели. Већ имамо табелу особа која садржи следеће податке:
Затим ћемо креирати још две табеле са именом 'позиција' , и ' персон_поситион ' користећи следећу изјаву:
CREATE TABLE POSITION ( PositionID INT IDENTITY (1, 1) PRIMARY KEY, Position_name VARCHAR (255) NOT NULL ); CREATE TABLE person_position ( PersonID INT, PositionID INT, PRIMARY KEY (PersonID, PositionID), FOREIGN KEY (PersonID) REFERENCES person (PersonID), FOREIGN KEY (PositionID) REFERENCES POSITION (PositionID) );
Затим покушавамо да убацимо нови запис у табелу особа и доделимо им позицију додавањем новог реда у табелу персон_поситион. То ћемо урадити користећи исказ трансакције као што је доле:
BEGIN TRANSACTION BEGIN TRY -- insert a new row into the person table INSERT INTO person (Fullname, Occupation, Gender) VALUES('Joan Smith', 'Manager', 'Male'); -- assign a position to a new person INSERT INTO person_position (PersonID, PositionID) VALUES(@@IDENTITY, 10); END TRY BEGIN CATCH IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION; END CATCH IF @@TRANCOUNT > 0 COMMIT TRANSACTION;
Горња скрипта кода трансакције успешно извршава прву наредбу уметања. Али друга изјава није успела јер није било позиције са ИД десет у табели позиција. Дакле, цела трансакција је враћена.
Пошто је максимална вредност идентитета у колони ПерсонИД 16, први израз за уметање је искористио вредност идентитета 17, а затим је трансакција враћена. Стога, ако убацимо следећи ред у табелу Персон, следећа вредност идентитета ће бити 18. Извршите наредбу у наставку:
INSERT INTO person(Fullname, Occupation, Gender) VALUES('Peter Drucker',' Writer', 'Female');
Након што поново проверимо табелу особа, видимо да новододати запис садржи вредност идентитета 18.
Две колоне ИДЕНТИТИ у једној табели
Технички, није могуће направити две колоне идентитета у једној табели. Ако то урадимо, СКЛ Сервер ће приказати грешку. Погледајте следећи упит:
CREATE TABLE TwoIdentityTable ( ID1 INT IDENTITY (10, 1) NOT NULL, ID2 INT IDENTITY (100, 1) NOT NULL )
Када извршимо овај код, видећемо следећу грешку:
Међутим, можемо да креирамо две колоне идентитета у једној табели користећи израчунату колону. Следећи упит креира табелу са израчунатом колоном која користи оригиналну колону идентитета и смањује је за 1.
CREATE TABLE TwoIdentityTable ( ID1 INT IDENTITY (10, 1) NOT NULL, SecondID AS 10000-ID1, Descriptions VARCHAR(60) )
Затим ћемо додати неке податке у ову табелу користећи следећу команду:
INSERT INTO TwoIdentityTable (Descriptions) VALUES ('Javatpoint provides best educational tutorials'), ('www.javatpoint.com')
На крају, проверавамо податке табеле помоћу наредбе СЕЛЕЦТ. Враћа следећи излаз:
На слици можемо видети како колона СецондИД делује као друга колона идентитета, смањујући се за десет од почетне вредности од 9990.
Погрешна схватања колоне ИДЕНТИТИ СКЛ Сервера
ДБА корисник има много заблуда у вези са колонама идентитета СКЛ Сервера. Следи листа најчешћих заблуда у вези са колонама идентитета које би се могле видети:
Колона ИДЕНТИТИ је УНИКУЕ: Према званичној документацији СКЛ Сервера, својство идентитета не може гарантовати да је вредност колоне јединствена. Морамо да користимо ПРИМАРИ КЕИ, УНИКУЕ ограничење или УНИКУЕ индекс да бисмо применили јединственост колоне.
Колона ИДЕНТИТИ генерише узастопне бројеве: Званична документација јасно каже да се додељене вредности у колони идентитета могу изгубити након квара базе података или поновног покретања сервера. То може проузроковати празнине у вредности идентитета током уметања. Размак се такође може створити када избришемо вредност из табеле или се наредба уметања врати назад. Вредности које стварају празнине не могу се даље користити.
Колона ИДЕНТИТИ не може аутоматски да генерише постојеће вредности: Није могуће да колона идентитета аутоматски генерише постојеће вредности док се својство идентитета поново не замени коришћењем команде ДБЦЦ ЦХЕЦКИДЕНТ. Омогућава нам да прилагодимо почетну вредност (почетну вредност реда) својства идентитета. Након извршења ове команде, СКЛ Сервер неће проверити новокреиране вредности које су већ присутне у табели или не.
Колона ИДЕНТИТИ као ПРИМАРНИ КЉУЧ је довољна да идентификује ред: Ако примарни кључ садржи колону идентитета у табели без других јединствених ограничења, колона може да складишти дуплиране вредности и спречи јединственост колоне. Као што знамо, примарни кључ не може да складишти дупликате вредности, али колона идентитета може да чува дупликате; препоручује се да се примарни кључ и својство идентитета не користе у истој колони.
Коришћење погрешног алата за враћање вредности идентитета након уметања: Такође је уобичајена заблуда о несвесности разлика између функција @@ИДЕНТИТИ, СЦОПЕ_ИДЕНТИТИ(), ИДЕНТ_ЦУРРЕНТ и ИДЕНТИТИ() да се вредност идентитета директно убаци из наредбе коју смо управо извршили.
Разлика између СЕКУЕНЦЕ и ИДЕНТИТИ
Користимо и СЕКУЕНЦЕ и ИДЕНТИТИ за генерисање аутоматских бројева. Међутим, он има неке разлике, а главна разлика је у томе што је идентитет зависан од табеле, док секвенца није. Хајде да сумирамо њихове разлике у табеларни облик:
ИДЕНТИТЕТ | НИЗ |
---|---|
Својство идентитета се користи за одређену табелу и не може се делити са другим табелама. | ДБА дефинише објекат секвенце који се може делити међу више табела јер је независан од табеле. |
Ово својство аутоматски генерише вредности сваки пут када се у табели изврши наредба уметања. | Користи клаузулу НЕКСТ ВАЛУЕ ФОР да генерише следећу вредност за објекат секвенце. |
СКЛ Сервер не ресетује вредност колоне својства идентитета на почетну вредност. | СКЛ Сервер може да ресетује вредност за објекат секвенце. |
Не можемо поставити максималну вредност за својство идентитета. | Можемо поставити максималну вредност за објекат секвенце. |
Уведен је у СКЛ Сервер 2000. | Уведен је у СКЛ Сервер 2012. |
Ово својство не може да генерише вредност идентитета у опадајућем редоследу. | Може да генерише вредности у опадајућем редоследу. |
Закључак
Овај чланак ће дати потпуни преглед својства ИДЕНТИТИ у СКЛ Серверу. Овде смо научили како и када се користи својство идентитета, његове различите функције, заблуде и како се разликује од секвенце.