Вставка рядків в таблицю, яка містить автоінкрементіруемое поле

Багато комерційних продуктів допускають використання автоінкрементіруемих стовпців в таблицях, тобто полів, значення яких формується автоматично при додаванні нових записів. Такі стовпчики широко використовуються в якості первинних ключів таблиці, тому що вони автоматично забезпечують унікальність. Типовим прикладом стовпчика такого типу є послідовний лічильник, який при вставці рядка генерує значення на одиницю більше попереднього значення (значення, отриманого при вставці попереднього рядка).

Нижче наводиться приклад створення таблиці з автоінкрементіруемим стовпцем (code) в MS SQL Server.

CREATE TABLE [Printer_Inc] ([code] [int] IDENTITY (1,1) PRIMARY KEY. [Model] [varchar] (4) NOT NULL. [Color] [char] (1) NOT NULL. [Type] [varchar ] (6) NOT NULL. [price] [float] NOT NULL)

Автоінкрементіруемое поле визначається за допомогою конструкції IDENTITY (1, 1). При цьому перший параметр властивості IDENTITY (1) визначає, з якого значення почнеться відлік, а другий - який крок буде використовуватися для збільшення значення. Таким чином, в нашому прикладі перша вставлена ​​запис буде мати в стовпці code значення 1, друга - 2 і т.д.

Оскільки в поле code значення формується автоматично, оператор

INSERT INTO Printer_Inc VALUES (15, 3111, 'y', 'laser', 2599);

призведе до помилки, навіть якщо в таблиці немає рядка із значенням в полі code. рівним 15. Тому для вставки рядка в таблицю просто не будемо вказувати це поле точно так же, як і в разі використання значення за замовчуванням, тобто

INSERT INTO Printer_Inc (model, color, type, price) VALUES (3111, 'y', 'laser', 2599);

В результаті виконання цього оператора в таблицю Printer_Inc буде вставлена ​​інформація про моделі 3111 кольорового лазерного принтера, вартість якого дорівнює $ 2599. В поле code виявиться значення, яке тільки випадково може виявитися рівним 15. У більшості випадків цього виявляється достатньо, тому що значення автоінкрементіруемого поля, як правило, не несе ніякої інформації; головне, щоб воно було унікальним.

Однак бувають випадки, коли потрібно підставити цілком конкретне значення в автоінкрементіруемое поле. Наприклад, потрібно перенести вже наявні дані в новостворювану структуру; при цьому ці дані беруть участь в зв'язку "один-ко-многим" з боку "один". Таким чином, ми не можемо допустити тут свавілля. З іншого боку, нам не хочеться відмовлятися від автоінкрементіруемого поля, тому що воно спростить обробку даних при подальшій експлуатації бази даних.

Оскільки стандарт мови SQL допускає наявність автоінкрементіруемих полів, то відповідно не існує і єдиного підходу. Тут ми покажемо, як це реалізується в MS SQL Server. оператор

відключає (значення ON) або включає (OFF) використання автоінкремента. Тому щоб вставити рядок зі значенням 15 в поле code. потрібно написати

SET IDENTITY_INSERT Printer_Inc ON; INSERT INTO Printer_Inc (code, model, color, type, price) VALUES (15, 3111, 'y', 'laser', 2599);

Зверніть увагу, що список стовпців в цьому випадку є обов'язковим, тобто ми не можемо написати так:

SET IDENTITY_INSERT Printer_Inc ON; INSERT INTO Printer_Inc VALUES (15, 3111, 'y', 'laser', 2599);

ні, тим більше, так

SET IDENTITY_INSERT Printer_Inc ON; INSERT INTO Printer_Inc (model, color, type, price) VALUES (3111, 'y', 'laser', 2599);

В останньому випадку в пропущений стовпець code значення не може бути підставлений автоматично, тому що автоінкрементірованіе відключено.

Важливо відзначити, що якщо значення 15 виявиться максимальним в стовпці code, то далі нумерація продовжиться зі значення 16. Природно, якщо включити автоінкрементірованіе: SET IDENTITY_INSERT Printer_Inc OFF.

Нарешті, розглянемо приклад вставки даних з таблиці Product в таблицю Product_Inc. зберігши значення в поле code:

SET IDENTITY_INSERT Printer_Inc ON; INSERT INTO Printer_Inc (code, model, color, type, price) SELECT * FROM Printer;

З приводу автоінкрементіруемих стовпців слід ще сказати наступне. Нехай останнє значення в поле code дорівнювало 16, після чого рядок з цим значенням була видалена. Яке значення буде в цьому стовпці після створити новий рядок? Правильно, 17, тому що останнє значення лічильника зберігається, незважаючи на видалення рядка, його містить. Тому нумерація значень в результаті видалення і додавання рядків не буде послідовною. Це є ще однією причиною для вставки рядка із заданим (пропущеним) значенням в автоінкрементіруемом стовпці.