Вставка строк в таблицу только с одним столбцом IDENTITY - PullRequest
75 голосов
/ 07 ноября 2010

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

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

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

Ответы [ 3 ]

131 голосов
/ 07 ноября 2010

Если у вас есть один столбец, который является ИДЕНТИЧНОСТЬЮ, просто сделайте это

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 голос
/ 07 ноября 2010

Вам необходимо добавить 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

0 голосов
/ 07 ноября 2010

@ Фил: Разве вы не имеете в виду, что ваша таблица имеет два (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 Вы упоминаете, что не знали, как «вставить значение», если вы «не было ничего, чтобы вставить ".Там есть противоречие.Если вам нечего вставить, зачем вставлять?Зачем вам создавать, скажем, новую запись CUSTOMER, если вы абсолютно ничего не знаете о клиенте?Не их имя, их город, их номер телефона, ничего?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...