максимальное значение при вставке в - PullRequest
0 голосов
/ 21 октября 2019

Мне нужно получить максимальное число в столбце, потому что в операции вставки мне нужно вставить максимальное число в этом столбце +1 для каждой вставки, я сделал это:

insert into table1(id ,.., field,...)
select newid(), ..., (SELECT CONVERT(VARCHAR(8), FORMAT((MAX(number)+1),'00000000'))
   FROM table1)

Это работает только дляпервая вставленная строка, чем я получаю это число и для других строк!

Ответы [ 3 ]

1 голос
/ 21 октября 2019

Здесь есть что комментировать, и, как и Гордон, я не могу вписать это в один.

Во-первых, я заметил, что у вас есть столбец id, и вы вставили значение NEWID() внутрь. Поэтому я надеюсь , что id не ваш CLUSTERED INDEX, как будто он NEWID() не оказывает ему никакой пользы. Если вы используете uniqueindentifier для своего CLUSTERED INDEX, используйте вместо него NEWSEQUENTIALID() и не указывайте значение в INSERT:

ALTER TABLE dbo.Table1 ADD CONSTRAINT DF_Table1_id DEFAULT NEWSEQUENTIALID() FOR id;

Что касается вашего INSERT, то какЯ сказал в своем комментарии: "Использовать столбец IDENTITY. Если вы должны , а затем иметь последовательные значения, используйте VIEW и ROW_NUMBER. Пусть SQL Server изящно обрабатывает увеличивающееся значение. Попытка увеличить число самостоятельно приведет только к проблемам, таким как состояние гонки, и ваши данные окажутся в гораздо худшем положении. ". К сожалению, вы не можете изменить существующий столбец на IDENTITY, так что это немного сложнее. Скорее всего, вы захотите сделать что-то вроде:

ALTER TABLE dbo.Table1 ADD number_new int IDENTITY(1,1);
GO

SET IDENTITY_INSERT dbo.Table1 ON;
--UPdate the new column with the existing values
UPDATE dbo.Table1
SET number_new = number;

SET IDENTITY_INSERT dbo.Table1 OFF;
GO
--Drop the old column and rename
ALTER TABLE dbo.Table1 DROP COLUMN number;
EXEC sp_rename N'dbo.Table1.number_new', N'number', N'COLUMN'

Как сказал Гордон, если вам просто нужно отформатированное значение (с ведущими 0) и не беспокоиться о пробелах, используйте вычисляемый столбец:

ALTER TABLE dbo.Table1 ADD Number_f AS RIGHT(CONCAT('00000000',number),8) PERSISTED;

Если, однако, вы хотите, чтобы они были в последовательном порядке и обновлялись соответствующим образом при удалении строки или при сбое INSERT и т. Д., Вы можете использовать представление со следующим выражением:

RIGHT(CONCAT('00000000',ROW_NUMBER() OVER (ORDER BY number ASC),8)
1 голос
/ 21 октября 2019

Это слишком долго для комментария.

Почему вы не используете столбец идентификаторов? Вы можете определить число следующим образом:

number int identity(1, 1)

Если вы хотите, чтобы значение в виде строки дополнялось восемью символами, используйте вычисляемый столбец:

number_string as (format(number, '00000000')) 

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

Существуют веские причины, по которым вам нужен столбец identity, а не рассчитывать значения самостоятельно. Вы можете делать то, что хотите, используя row_number(), где логика выглядит следующим образом:

insert into table1(id ,.., field,...)
    select newid(), ...,
           convert(varchar(8),
                   (coalesce(t1.max_number, 0) + 
                    row_number() over (order by (select null))
                   )
                  )
     from table2 t2 cross join
          (select max(t1.number) as max_number from table1 t1) t1;

N

Примечание: я предполагаю, что вставки происходят из другой таблицы, но table2 действительно может быть table1.

Очень важно: Это не потокобезопасно. Два разных потока могут запускать один и тот же код и приводить к одним и тем же значениям. Решением этой проблемы является блокировка всей таблицы. Однако это может оказать очень значительное влияние на производительность.

0 голосов
/ 21 октября 2019

Вы можете использовать функцию ROW_NUMBER() для увеличения идентификаторов. Просто замените +1 на ROW_NUMBER() OVER(). Примерно так:

insert into table1(id ,.., field,...)
select (SELECT MAX(number) FROM table1) + ROW_NUMBER() OVER(ORDER BY <field1>), ...
from table1

SQL Fiddle

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