2016-02-16 8 views
1

В этом случае у меня есть таблица Plant_Component, у которой есть столбец CODE. Мы добавили в наш веб-приложение код для автоматического вычисления значения, которое поступит в Plant_Component.CODE для новых вставленных записей, и теперь я должен выполнить некоторую очистку и вставить правильное значение в таблицу Plant_Component с CODE = 'testcode'.Обновление нескольких записей с различными инкрементальными значениями

Логика для вычисления кода является:

  • Получить все значения из Plant_Component.CODE
  • Выберите только значения Wich являются целыми числами
  • Из этих целочисленных значений, получить максимум
  • Добавить 1 до максимального значения, и это мой код.

Запрос я использовал:

UPDATE Plant_Component 
SET CODE = CONVERT(varchar, CONVERT(integer, PCread.CODE) + 1) 
FROM 
    (SELECT CODE 
    FROM Plant_Component 
    WHERE ISNUMERIC(CODE) = 1 
    AND CODE NOT LIKE '%[^0-9]%' 
) AS PCread 
WHERE Plant_Component.CODE = 'testcode' 

Проблема заключается в том же значение получает вставляется в каждой строке, пострадавших от этого запроса. Чтобы объяснить себя, когда я проверил это, мое максимальное целочисленное значение было 507007, и каждая затронутая строка была обновлена ​​значением 507008 ...

Есть ли способ сделать это так, чтобы каждая другая затронутая строка увеличивала это значение на 1 ?

Пример: Если в данный момент я запускаю запрос мой максимальный код является 507007, и запрос затрагивает три записи, я думаю, эти три записи, чтобы иметь код соответственно 507008, 507009, 507010.

ПРИМЕЧАНИЕ: Я знаете, как я определяю значение как целое, не является надежным, но это одноразовый скрипт, и я знаю, что не будет никаких значений, которые заставят это получить ошибку (например, я думаю, значение «999999999999999999999999999999999999» 'может привести к аварии)

+0

Вы пытались установить FROM Plant_Component и присоединиться к текущей части FROM, а затем выбрать PCread.CODE? Я полагаю, потому что у вас нет компонента Plant_Component, запрос предполагает обновить всю таблицу с первым значением, которое она находит. Однако не проверял. – martennis

ответ

2

Вы можете использовать CTE как более удобный способ для проведения UPDATE:

;WITH ToUpdate AS (
    SELECT p.CODE AS CODE, 
     ROW_NUMBER() OVER (ORDER BY CODE) + t.maxVal AS newCode 
    FROM Plant_Component AS p 
    CROSS JOIN (
    SELECT MAX(CAST(CODE AS integer)) AS maxVal 
    FROM Plant_Component 
    WHERE ISNUMERIC(CODE) = 1 AND CODE NOT LIKE '%[^0-9]%') AS t 
    WHERE p.CODE = 'testcode' 
) 
UPDATE ToUpdate 
SET CODE = CAST(newCode AS VARCHAR(100)) 

Примечание: Вы должны CAST или CONVERT с использованием параметра длины, а также. Я предполагаю, что ваше поле CODE имеет тип VARCHAR(100).

+0

Это сработало, спасибо! –

1

добавить это перед кодом:

DECLARE @a int SET @a = 1

Затем обновите update раздел в коде, как это:

SET CODE = CONVERT(varchar, CONVERT(integer, PCread.CODE) + @a), @a:[email protected]+1

+0

Идея этого решения приятная и простая, мне это нравится, но когда я попытался ее реализовать, я получил некоторую синтаксическую ошибку. Спасибо! –

+0

@FabioLolli Это решение MySQL, я думаю. –

+1

Нет, это MS SQL, но, к сожалению, я совершил небольшую ошибку, исправляю ее – wajeeh

2

попробовать это:

Declare @id int 
select @id = isnull(max(code),0)+1 from plant_component 
Update plant_component set code = @id, @[email protected]+1 where code is null 
0

Yo u может попытаться использовать функцию окна ROW_NUMBER() в CTE для генерации порядковых номеров для строк, которые необходимо обновить. Затем вы можете добавить это число к максимальному значению любых числовых значений в таблице.

Вы не указали, какие другие поля у вас есть в таблице, но я предположил, что у вас есть какой-то первичный ключ, который потребуется для присоединения CTE к базовой таблице для UPDATE. Мой пример имеет PK 'id' типа int. Моя оконная функция ROW_NUMBER() разбивается на столбец CODE, что означает, что ROW_NUMBER сбрасывается до 1 для каждого различного нечислового значения CODE, если у вас есть.

with cte as (select id, CODE, ROW_NUMBER() over (partition by CODE order by CODE) as rownum 
from Plant_Component 
WHERE Plant_Component.CODE = 'testcode') 

UPDATE Plant_Component 
SET CODE = CONVERT(varchar, rownum + (select max(convert(int,CODE)) from Plant_Component WHERE ISNUMERIC(CODE) = 1)) 
FROM cte, Plant_Component 
where cte.id = Plant_Component.id 

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

Я надеюсь, что это поможет.

Смежные вопросы