Создайте временную таблицу и выполните цикл по строкам, чтобы выполнить обновление для другой таблицы. - PullRequest
0 голосов
/ 17 октября 2019

Я пытаюсь преобразовать данные из существующей таблицы во временную таблицу и перебрать строки для обновления данных существующей таблицы.

Мне нужно сократить столбец DeviceName и привестикак INT для извлечения идентификаторов DevicesID, которые потребуются для обновления существующей таблицы. Первая таблица показывает пример неформатированного DeviceName. Вторая таблица показывает пример форматированного DeviceName (DeviceIntModified). Затем мне нужно получить эти DevicesID, чтобы я мог использовать их для обновления существующей таблицы.

Моя исходная таблица tblDevices:

----------------------------------------------------
DeviceName          |   DevicesID   |   StationID
----------------------------------------------------
MainStation-464     |   1163        |   14
MainStation-465     |   1164        |   14
MainStation-466     |   1165        |   14
MainStation-467     |   1166        |   14
----------------------------------------------------
WITH tempTable as 
(
   SELECT
      DevicesID,
      RIGHT(DeviceName, LEN(DeviceName) - 12) AS DeviceNameModidfied
   FROM
      tblDevices 
   where
      StationID = 14 
)
select
   CAST (DeviceNameModidfied as int) as DeviceIntModified,
   DevicesID 
from
   tempTable 
where
   DeviceNameModidfied > 464 
   AND DeviceNameModidfied < 467

Это прекрасно работает иприводит к следующему недавно созданному tempTable:

----------------------------------
DeviceIntModified   |   DevicesID
----------------------------------
        465         |   1164
        466         |   1165
----------------------------------

У меня проблемы с выбором данных из этой таблицы и циклическим просмотром данных.

DECLARE @RowCount INT WITH tempTable as 
(
   SELECT
      DevicesID,
      RIGHT(DeviceName, LEN(DeviceName) - 9) AS DeviceNameModidfied 
   FROM
      tblDevices 
   where
      StationID = 14 
)
select
   CAST (DeviceNameModidfied as int) as DeviceIntModified,
   DevicesID 
from
   tempTable 
where
   DeviceNameModidfied > 464 
   AND DeviceNameModidfied < 500 
SET
   @RowCount = 
   (
      SELECT
         COUNT(DevicesID) 
      from
         tempTable
   )
   DECLARE @I INT 
SET
   @I = 1 WHILE (@I <= @RowCount) 
   BEGIN
      DECLARE @rowID INT 
      --I'm getting invalid column/object name when trying to select from tempTable here
      SELECT
         @rowID = DevicesID 
      from
         tempTable 
         UPDATE
            anotherTable                
            SET CheckBox = 'T'
         WHERE
            DevicesID = @rowID 
         SET
            @I = @I + 1 
   END

Результаты должны выглядеть примерно так: anotherTable:

----------------------------------
    CheckBox        |   DevicesID
----------------------------------
        T           |   1164
        T           |   1165
----------------------------------

Ответы [ 2 ]

2 голосов
/ 17 октября 2019

Вы можете обновить CTE напрямую, но в этом случае вы можете просто использовать предложение о существовании. Критерии объединения могут отличаться, если ваш пример не точен. Предложение Существует над внутренним объединением, потому что вам не нужно просматривать возвращенные записи, что делает этот подход предпочтительным.

WITH tempTable as 
(
   SELECT
      DevicesID,
      RIGHT(DeviceName, LEN(DeviceName) - 12) AS DeviceNameModidfied
   FROM
      tblDevices 
   where
      StationID = 14 
)
, TempTable_2 as (
select
   CAST (DeviceNameModidfied as int) as DeviceIntModified,
   DevicesID 
from
   tempTable 
where
   DeviceNameModidfied > 464 
   AND DeviceNameModidfied < 467
)
Update SomeOtherTable
Set CheckBox = 'T'
where exists (select 1 from TempTable_2 tt where DeviceID = tt.DeviceID);
0 голосов
/ 17 октября 2019

Вы можете избежать зацикливания и даже CTE, если используете синтаксис обновления, который позволяет вам присоединяться к «anotherTable» прямо в самом запросе.

update      other.checkbox = 't'
from        anotherTable other 
join        tblDevices td on td.devicesId = other.devicesId
cross apply (select DeviceNameMod = convert(int,right(DeviceName, len(DeviceName) - 12))) ap
where       td.StationID = 14 
and         ap.DeviceNameMod > 464 
and         ap.DeviceNameMod < 500;

Но если вы продолжите свой первоначальный подхододна из ваших больших проблем заключается в том, что ваш @rowID используется как итератор, который должен быть от 0 до n-1 или от 1 до n, но вы заполняете его 'DevicesId', что, безусловно, неработать так.

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