1

в моей базе данных SQL Server 2005 У меня есть столбец RMA_Number с типом datatype char (10) в таблице RMA.MAX/ORDER BY on char column

Значение увеличивается с номером RMA0002511. Каков самый быстрый способ получить наибольшее число, чтобы увеличить его при вставке?

Мой первый подход:

SELECT  TOP (1) RMA_Number 
FROM   RMA 
WHERE  (RMA_generated = 1) 
ORDER BY Creation_Date DESC 

Но это был подвержен ошибкам, потому что это как-то возможно, что выше RMA_Number имеет более раннюю дату создания. В качестве обходного пути сортировка по первичному ключе работает:

SELECT  TOP (1) RMA_Number 
FROM   RMA 
WHERE  (RMA_generated = 1) 
ORDER BY idRMA DESC 

Но, возможно, это также возможный источник ошибок.

Логически лучшим способом было бы ORDER BY RMA_Number DESC.

Но поскольку я не был уверен, что это всегда дает правильный результат, и подумал, что сортировка столбца char может замедляться, если количество записей увеличивается, я выбрал порядок по столбцу Date.

Так,

  1. это хорошая идея, чтобы заказать по полукокса (10) -column (производительность и точность)?
  2. было бы лучше SELECT MAX(RMA_Number) FROM RMA, чтобы получить наибольшее количество (Perf. И точность)
  3. я должен придерживаться на использование первичного ключа к порядку, если первые два пункта является неправильным или я должен использовать int колонки и формат номер в приложении?

EDIT:

Я думаю, что я должен что-то уточнить, что я не упомянул. RMA_Number не создается для каждой вставки. Так что, возможно, есть много записей без номера. Мартин использует первичный ключ для создания номера. Это было бы проблемой, потому что пробелы были бы слишком большими.

Заранее спасибо.

+0

Имеет ли значение, если промежутки времени появляются в значениях? Например, было бы хорошо иметь RMA0002511 и RMA0002513, но не RMA0002512? – 2010-12-01 14:39:09

+0

Это не проблема. На самом деле это происходит, если я удаляю более старую запись. – 2010-12-01 14:45:10

+0

Поскольку пробелы в порядке, я бы порекомендовал колонку идентификации, как в ответе @ Мартина. – 2010-12-01 14:51:00

ответ

7

Самый быстрый и безопасный способ (для параллелизма) - это не хранить префикс RMA000....

Просто создайте целочисленный столбец идентификаторов и добавьте префикс через вычисленный столбец.

create table #RMA 
(
id int identity(2511,1) primary key, 
RMA_Number as 'RMA' + RIGHT('000000' + CAST(id as varchar(7)),7) 
) 

insert into #RMA 
default values 

select * from #RMA 

Или после новой информации, что не все записи имеют RMA_Number вы могли бы использовать этот подход для не блокированием, эффективное и безопасное решение параллелизм.

CREATE TABLE dbo.Sequence(
val int IDENTITY (2511, 2) /*Seed this at 1 + whatever your current max value is*/ 
) 

GO 

/*Call this procedure to get allocated the next sequence number to use*/  
CREATE PROC dbo.GetSequence 
@val AS int OUTPUT 
AS 
BEGIN TRAN 
    SAVE TRAN S1 
    INSERT INTO dbo.Sequence DEFAULT VALUES 
    SET @val=SCOPE_IDENTITY() 
    ROLLBACK TRAN S1 /*Rolls back just as far as the save point to prevent the 
         sequence table filling up. The id allocated won't be reused*/ 
COMMIT TRAN 
3

Во-первых, вы смотрите на серьезном скачках состоянии.

Когда мы нуждались в этом в проекте, с которым мы работали, у нас была отдельная таблица с текущим значением, хранящимся в ней, и функцией для создания следующего. Мы реализовали блокировку, чтобы сохранить несколько вызовов, чтобы получить следующий номер.Насколько я помню, это было связано с тем, что нам приходилось использовать буквенно-цифровые идентификационные номера (функция позаботилась о сложном приращении этого).

Однако, мне нравится решение @ Martin наилучшим образом: использовать и IDENTITY поле. Вы можете либо отбросить префикс, как он предлагает, либо просто отбросить его из столбца и добавить его обратно, когда SELECT ing из таблицы.