Вставка строк в таблицу только с одним столбцом IDENTITY

У меня есть администратор таблицы с только одним столбцом, adminId, который является основным ключом. Из-за бизнес-правил это должно быть так.

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

Мне бы очень хотелось не вставлять фиктивное значение, чтобы вставлять новую строку. Спасибо!

Ответ 1

Если у вас есть один столбец, который является IDENTITY, просто сделайте это

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

Ответ 2

Вам нужно добавить IDENTITY_INSERT в оператор select:

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

Ответ 3

@Phil: Разве вы не имеете в виду, что в вашей таблице есть два (2) столбца, столбец PK и индекс AdminName? Если он содержит только один столбец, куда входит AdminName, AdminName - это ПК, и вы, конечно, не можете автоинкремент строки. В бизнес-правилах вы ожидаете, что вы сделаете полное имя пользователя Windows основным ключом? Это было бы жизнеспособным и имело бы смысл, потому что тогда вам не понадобится альтернативный уникальный индекс в столбце AdminName.

Но если ваша таблица имеет два столбца, а не один:

В SQLServer автоинкремент является частью определения таблицы/столбца. Вы определяете столбец как целое число, а затем столбец идентичности, указав приращение, обычно 1, но может быть 2 или 5 или 10 или что угодно. Чтобы вставить строку, вы просто вставляете другие значения столбцов (столбцов) и ничего не делаете с столбцом PK:

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

Ваш сохраненный proc, который делает вставку, может сделать SCOPE_IDENTITY значением RETURN, или SCOPE_IDENTITY можно передать клиенту в качестве параметра OUT.

P.S. SCOPE_IDENTITY() возвращает самое последнее сгенерированное значение автоинкрементной идентификации в текущей области; он не генерирует следующее значение идентификации.

EDIT:

Предположительно, ваша таблица "Администраторы" содержит набор администраторов. Но если в нем нет столбцов, отличных от целочисленного столбца первичного ключа, невозможно определить администраторов; единственное, что вы можете сделать, это отличить их друг от друга. Это совсем не очень сильно. Но если ваша таблица администратора имела одну из следующих структур:

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();

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

P.S. Вы упомянули, что не знали, как "вставить значение", если вам "нечего было вставлять". Там есть противоречие. Если вам нечего вставлять, зачем вставлять? Зачем вам создавать, скажем, новую запись CUSTOMER, если вы абсолютно ничего не знаете о клиенте? Не их имя, их город, их номер телефона, ничего?

Ответ 4

Всякий раз, когда мы устанавливаем свойство identity столбца "On", нам не нужно явно вставлять значения в этот столбец. SQL Server неявно вставляет значения в столбец идентификаторов на основе инкрементного значения. Здесь мы увидим, как мы можем явно вставлять значения в столбец идентификаторов. Прежде всего, мы создадим таблицу с идентификационным столбцом.

Ниже приведена script для создания таблицы с идентификационным столбцом: -

create table Identitytable(id int identity,Name varchar(50))

В таблице "Identitytable" я определил столбец "Id" в качестве столбца идентификации. Позволяет вставить несколько строк в эту таблицу без явной вставки значений в столбец "Id" .

insert into Identitytable(Name) values('Neeraj')
insert into Identitytable(Name) values('Raj')
insert into Identitytable(Name) values('Akshay')
insert into Identitytable(Name) values('Ankit')
insert into Identitytable(Name) values('Vikas')

Мы будем работать над script, чтобы вставить 5 строк в таблицу "Identitytable" и проверить, что вставляется в таблицу.

В приведенном выше изображении мы можем увидеть значения для столбца id (1,2,3,4,5), в то время как мы явно не вставляем значения в столбец "Id" . Теперь попробуйте вставить значения в ящик "Id" явно.

В приведенном ниже script мы пытаемся вставить значение "9" в столбец "Id" явно, посмотрим, каков результат следующего запроса insert.

insert into Identitytable(Id,Name) values(9,'Mamta')