Как обновить значение с помощью предложения With в SQL - PullRequest
0 голосов
/ 07 сентября 2018

Я хотел бы обновить столбец таблицы на основе результата, который находится внутри предложения «С».Когда я использую tb в операторе обновления, он отображает недопустимое имя объекта, так как оно уже находится в предложении «С».Если бы кто-нибудь мог помочь мне в этом.Спасибо!

;WITH Split_Segments AS 
(
    SELECT 
        W.ROW_ID
    FROM 
        table1 W
    WHERE
        W.ERRORS IS NULL AND W.UserName = @userId
),
tb AS 
(
    SELECT DISTINCT
        ROW_ID, AP
    FROM 
        Split_Segments 
    WHERE 
        LEN(AP) <> 3  
)
SELECT 
    A.ROW_ID
INTO 
    #tempTable
FROM
    Split_Segments  A
INNER JOIN 
    table4 B ON A.ROW_ID = B.ROW_ID
             AND A.AP = B.AP
LEFT OUTER JOIN 
    tb Z ON A.ROW_ID = Z.ROW_ID
WHERE 
    Z.AP IS NULL;

Я хотел бы выполнить следующую инструкцию:

UPDATE W SET ERRORS = 'Error' 
FROM table5 W
INNER JOIN tb T ON W.ROW_ID = T.ROW_ID
WHERE AP IS NOT NULL;

Ответы [ 2 ]

0 голосов
/ 08 сентября 2018

Хорошо, если я правильно понял, это обновление, которое вы хотите выполнить, верно? UPDATE W SET ERRORS = 'Error' FROM table5 W INNER JOIN tb T ON W.ROW_ID = T.ROW_ID WHERE AP IS NOT NULL;

Чтобы это работало, вам нужен tb, который является CTE ... поэтому добавьте его:

;WITH tb AS ( SELECT DISTINCT ROW_ID, AP FROM Split_Segments WHERE LEN(AP) <> 3<br> ) UPDATE W SET ERRORS = 'Error' FROM table5 W INNER JOIN tb T ON W.ROW_ID = T.ROW_ID WHERE AP IS NOT NULL;

Теперь tb также нужен Split_Segments, который также является CTE, поэтому его также необходимо включить ...

;WITH Split_Segments AS ( SELECT W.ROW_ID FROM table1 W WHERE W.ERRORS IS NULL AND W.UserName = @userId ),tb AS ( SELECT DISTINCT ROW_ID, AP FROM Split_Segments WHERE LEN(AP) <> 3<br> ) UPDATE W SET ERRORS = 'Error' FROM table5 W INNER JOIN tb T ON W.ROW_ID = T.ROW_ID WHERE AP IS NOT NULL;

Там ... теперь это должно работать ... в обновлении нет ничего, что требовало бы временную таблицу или что-либо еще, кроме CTE ....

0 голосов
/ 07 сентября 2018

Вы можете запустить только один SELECT или UPDATE в конце оператора WITH. Поскольку вы указали, что вам нужен доступ к #tempTable за пределами этого предложения CTE, но эта таблица опирается на tb для его построения, я бы предложил также перенести tb во временную таблицу:

Удалить tb из предложения WITH:

 --Provisioning tb as temp table outside of CTE
 SELECT DISTINCT 
   ROW_ID, 
   AP
 INTO tb
 FROM table2
 WHERE LEN(AP) <> 3;

--Provisioning temp table outside of CTE
SELECT A.ROW_ID
INTO #tempTable
FROM table3 A
  INNER JOIN table4 B ON A.ROW_ID = B.ROW_ID
    AND A.AP = B.AP
  LEFT OUTER JOIN tb Z ON A.ROW_ID = Z.ROW_ID
WHERE Z.AP IS NULL;

WITH Split_Segments AS (
    SELECT 
      W.ROW_ID
    FROM 
      table1 W
    WHERE
      W.ERRORS IS NULL AND W.UserName = @userId)

UPDATE W SET ERRORS = 'Error' 
FROM table5 W
  INNER JOIN tb T ON W.ROW_ID = T.ROW_ID
WHERE AP is not null;

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

SELECT W.ROW_ID
INTO #tempSplit_Segments
FROM table1 W
WHERE W.ERRORS IS NULL AND W.UserName = @userId

SELECT DISTINCT ROW_ID, AP
FROM #tempSplit_Segments 
WHERE LEN(AP) <> 3;

SELECT A.ROW_ID
INTO #tempTable
FROM #tempSplit_Segments A
  INNER JOIN table4 B ON A.ROW_ID = B.ROW_ID
    AND A.AP = B.AP
  LEFT OUTER JOIN tb Z ON A.ROW_ID = Z.ROW_ID
WHERE Z.AP IS NULL;

UPDATE W SET ERRORS = 'Error' 
FROM table5 W
  INNER JOIN tb T ON W.ROW_ID = T.ROW_ID
WHERE AP is not null;
...