Сохраненная процедура SQL - помогите мне написать ее, пожалуйста!

Не могли бы вы помочь мне с этим:

В одном из моих сценариев я вставляю некоторые данные в некоторую таблицу «Элемент». Один из столбцов в таблице «Item» — «ItemNumber».

Я хочу иметь возможность вызывать некоторую функцию (скорее всего, хранимую процедуру), где она вернет мне числовое число, которое я могу использовать для ItemNumber.

Я НЕ МОГУ использовать автоинкремент, потому что ItemNumber уникален и может возникнуть коллизия, когда в другом скрипте я вставляю данные в "Item", у которого уже есть "ItemNumber"

Я знаю только максимальное число для «ItemNumber», и после этого я могу использовать что угодно.

Мне нужна таблица для этого storeProc для хранения следующего числа, которое будет использоваться, верно?

Я думал о создании таблицы из одного столбца с MaxNumber в ней и хранимой процедуре, где она вернет мне MaxNumber , а также увеличит MaxNumber на 1 для следующего использования

Мне нужна помощь в написании хранимой процедуры и ее использовании в вызове INSERT INTO Item.

РЕДАКТИРОВАТЬ:

В основном я беру данные из 5 старых таблиц, где ItemNumber имеет значение NULL или установлено. Для тех, которые установлены, все они являются уникальными номерами. Для данных, где ItemNumber имеет значение NULL, я хочу назначить его, какой лучший подход?

Помогите, пожалуйста!

Спасибо,

Вуду


person VoodooChild    schedule 30.06.2010    source источник
comment
Пожалуйста, постарайтесь сделать это более читабельным, если вы ожидаете хороших ответов. Очень трудно следить за ходом ваших мыслей   -  person Joe Phillips    schedule 30.06.2010
comment
Вставка строки из другого скрипта не вызовет коллизий с автоматически увеличивающимся идентификатором. Идентификаторы генерируются на сервере, а не вашим скриптом. Вы используете несколько баз данных или таблиц?   -  person Tom H    schedule 30.06.2010
comment
@Tom H: Да, я использую несколько таблиц и вставляю их в одну таблицу, некоторые данные строки имеют ItemNumber, а некоторые имеют значение null. Новая таблица данных требует, чтобы они были не нулевыми и уникальными в ItemNumber.   -  person VoodooChild    schedule 30.06.2010
comment
@Joe Phillips: я отредактировал его, но я не уверен, что он все еще понятен, пожалуйста, задавайте вопросы по той части, которая неясна, спасибо.   -  person VoodooChild    schedule 30.06.2010


Ответы (1)


(Предполагая, что SQL Server - вероятно, относится к большинству реализаций SQL)

Если вы используете ограничение IDENTITY для своего поля, сервер не допустит дублирования экземпляров. Как отмечается в одном из комментариев, в этом случае значение вычисляется на сервере, и ваше приложение его не предоставляет (и при нормальных обстоятельствах не может) предоставить.

Обратите внимание, что сервер не гарантирует, что числа будут непрерывными — если вы сделаете вставку и прервете транзакцию, значение, которое было бы использовано, будет «потеряно» — сервер не предложит его снова.

Если вам нужно иметь непрерывные идентификационные номера, вам потребуется серийный доступ для обновления таблицы, которым вам нужно будет управлять и который будет неэффективным. (Вы по-прежнему можете объявить его столбцом IDENTITY, но вам потребуется установить для таблицы значение IDENTITY_INSERT On для каждого обновления.)

Дополнительный:

Возможно, немного кладж, но может работать для одноразового сценария. Рассматривали ли вы копирование данных в новую таблицу, где установлен идентификатор, затем применение ограничения IDENTITY и вставку данных с нулевыми идентификаторами (позволяя серверу выделять их для вас?) Это может решить вашу конкретную проблему здесь.

person Ragster    schedule 30.06.2010
comment
Спасибо, еще один вопрос: скажем, используя IDENTITY, сервер дает мне 33 для использования в качестве ItemNumber, что произойдет, когда я попытаюсь вставить (используя Identity_Insert, как вы предложили), который имеет 33 в качестве ItemNumber? Это вызовет столкновение и не сработает. Мне нужно сохранить ItemNumbers такими же, как и раньше, и назначать только те, которые равны нулю. - person VoodooChild; 30.06.2010
comment
Если вы используете поля Identity, вы обычно не хотите указывать значение самостоятельно - дело в том, что вы позволяете серверу делать это (согласованным потокобезопасным способом). IDENTITY_INSERT используется, когда вы хотите отменить сервер для какая-то очень веская причина, и это не должно быть нормальной операцией. (Мы используем его для конкретной таблицы, где значения должны соответствовать другому полю идентификации по техническим причинам, а также очень редкое ручное восстановление данных - очень исключительные случаи.) - person Ragster; 30.06.2010
comment
(продолжение) Однако, если у вас есть существующие данные в таблице, вы можете применить ограничение с помощью NOCHECK, и это правило будет применяться только к новым вставкам. Вы можете вручную изменить существующие (в рамках правил для поля). Сервер никогда не вставит номер, который уже существует для поля идентификации. Он не «дает» вам номер для вставки — вы запрашиваете вставку записи, и он делает это, генерируя номер для вас. Затем вы можете спросить его, каким был последний вставленный идентификатор. - person Ragster; 30.06.2010
comment
Я добавил краткое предложение, которое может решить вашу конкретную проблему. Я бы не рекомендовал его для общего использования! - person Ragster; 30.06.2010