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


83

У мене є адміністратор таблиці лише з одним стовпцем, adminId, який є первинним ключем. Через ділові правила це повинно бути таким чином.

Я хотів би раз і назавжди зрозуміти, як я можу писати збережені процедури, які вставляють значення в такі таблиці. Я використовую SQL Server і T-SQL і намагався використовувати SCOPE_IDENTITY (), але це не працює, оскільки в таблиці INSERT_IDENTITY має значення false або off.

Я б дуже хотів не вставляти фіктивне значення лише для того, щоб мати можливість вставити новий рядок. Дякую!


1
Для уточнення: ваше питання "як вставити рядки в таблицю SQL Server з одним стовпцем IDENTITY"?
gbn

Так, ви маєте рацію, дякую за роз'яснення
Філ

2
Для людей , посадки тут, це було запропоновано до і правильну відповідь тут: stackoverflow.com/questions/850327 / ...
BJury

Відповіді:


140

Якщо у вас є один стовпець, який є ІДЕНТИФІКАЦІЄЮ, просто зробіть це

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

Якщо у вас немає особистості, то чи можете ви її встановити? Це найкращий спосіб .. і скористайтеся SQL вище.

Якщо ні, ви хочете вставити новий рядок

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

Примітки:

  • При великих навантаженнях рішення MAX може вийти з ладу з дублікатами
  • SCOPE_IDENTITY це після того, як насправді, не раніше
  • SCOPE_IDENTITY працює лише зі стовпцем IDENTITY. Подібно до будь-якого ідіотизму, використовуючи IDENT_CURRENT
  • Вихідне речення замінює SCOPE_IDENTITY для рішення MAX

1

Вам потрібно додати IDENTITY_INSERT до вибраного оператора:

SET IDENTITY_INSERT MyTable ON

INSERT INTO MyTable
(AdminCol)

SELECT AdminColValue

 FROM Tableb

Коли закінчите, обов’язково пам’ятайте про це

SET IDENTITY_INSERT MyTable OFF

Ось хороший опис того, як це працює від BOL: http://msdn.microsoft.com/en-us/library/aa259221(SQL.80).aspx


Чи повинен я робити це так: ВСТАНОВИТИ ІДЕНТИЧНІСТЬ_ІНСЕРТУ адміністратора УВІМКНУТИ В КОНТРОЛЕР (SCOPE_IDENTITY ()) ВСТАНОВИТИ ІДЕНТІСТЬ_ІНСЕРТУ адміністратора ВИМКНЕНО?
Філ

Так. Це все, що вам потрібно зробити. ВСТАНОВИТИ, написати код, ВИМКНУТИ в кінці.
DataWriter

Я не думаю, що це правильна відповідь. Якщо це стовпець ідентичності, ви не повинні додавати до нього значення. Прийнята відповідь - це правильна відповідь.
Ммм,

0

@Phil: Ви не маєте на увазі, що ваша таблиця має два (2) стовпці, стовпець PK, що автоматично збільшується, і стовпець AdminName? Якщо він має лише один стовпець, куди йде AdminName, AdminName - це PK, і ви не можете автоматично збільшити рядок, звичайно. Чи очікують ділові правила від вас, щоб зробити повністю кваліфікованим іменем користувача Windows первинний ключ? Це було б життєздатно і мало б сенс, оскільки тоді вам не знадобиться альтернативний унікальний індекс у стовпці AdminName.

Але якщо ваша таблиця має два стовпці, а не один:

У SQLServer автоінкремент є частиною визначення таблиці / стовпця. Ви визначаєте стовпець як ціле число, а потім також робите його ідентифікаційним стовпцем, вказуючи приріст, як правило, 1, але це може бути 2, 5 або 10 або що завгодно. Щоб вставити рядок, ви просто вставляєте значення інших стовпців (колонок) і нічого не робите зі стовпцем PK:

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

Ваш збережений процес, який виконує вставку, може зробити SCOPE_IDENTITY значенням RETURN або SCOPE_IDENTITY може бути переданий клієнту як параметр OUT.

PS SCOPE_IDENTITY () повертає останнє згенероване значення автоматичного збільшення ідентичності в поточній області; це не генерує наступне значення ідентичності.

РЕДАГУВАТИ:

Імовірно, ваша таблиця адміністраторів містить набір адміністраторів. Але якщо у нього немає жодних стовпців, крім цілочисельного стовпця первинного ключа, немає можливості ідентифікувати адміністраторів; єдине, що ви можете зробити, це відрізнити їх один від одного. Це зовсім не забирає вас далеко. Але якщо ваша таблиця Адміністратора мала будь-яку з таких структур:

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

АБО

windowsusername varchar(50) primary key

ви могли б посилатися на таблицю адміністратора з інших таблиць, а зовнішні ключі мали б значення. І саме цього не вистачає таблиці, що складається з одного цілочисельного стовпця - значення.

Маючи два стовпці, ви могли б мати збережену процедуру, щоб зробити це:

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

і ваша клієнтська програма поверне як значення, що повертається, автоінкрементований ідентифікатор, який був автоматично згенерований і призначений новоствореному рядку. Цей підхід є звичайною практикою, і я піду так далеко, що скажу, що він вважається "найкращою практикою".

PS Ви згадуєте, що не знали, як "вставити значення", якщо "не було чого вставити". Там є протиріччя. Якщо вам нічого вставити, навіщо вставляти? Навіщо вам створювати, скажімо, новий запис КЛІЄНТА, якщо ви абсолютно нічого не знаєте про замовника? Не їх ім’я, місто, номер телефону, нічого?


2
У моїй таблиці є ОДИН стовпець, adminId, який є додатковим значенням int
Філ

Це найдивніший дизайн, який я коли-небудь бачив, і я займаюсь цим бізнесом понад 20 років і бачив деякі дивні речі у свій час. Отже, ваше запитання полягає в тому, як ви вставляєте в таблицю, яка містить лише стовпець первинного ключа, визначений як стовпець ідентифікації, що автоматично збільшується, коли таблиця містить цей стовпець PK і лише цей стовпець PK, жодних інших стовпців немає.
Тим,

Отже, за що голосувати проти? Фактична помилка десь або висловлення думки про відсутність гідності дизайну?
Тім

1
Тільки для пояснення міркувань, що лежать в основі проектування DB. У нас є користувачі в одній таблиці. Якщо існує взаємозв'язок між користувачами та адміністраторами; до них відносяться як до адміністраторів. У таблиці адміністратора не можна зберігати нічого іншого, окрім фактичного унікального ідентифікатора. "Реальні" дані містяться в таблиці користувача та у відношенні has (з позначками часу та хто надав тощо).
Філ

1
@Phil: Отже, ви використовуєте таблицю та зв'язок із зовнішнім ключем, щоб виразити, що може зробити простий логічний / бітовий стовпець. Можливо, ви не зможете додати такий бітовий стовпець до своєї таблиці, і вам доведеться придумати якесь обхідне рішення. But an autoincrementing integer whose autoincrementation must be disabled is a poor solution.Все, що вам потрібно, це паралельна таблиця, яка має відношення один до одного з таблицею користувачів, і в цій таблиці ви створюєте бітовий стовпець. Коли цей стовпець істинний, це означає, що користувач має адміністратора. Чистий. Стандартний. Дизайн.
Тім
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.