Декодировать внутри оператора Case в SQL - PullRequest
1 голос
/ 16 сентября 2011

Почему этот запрос не имеет смысла? Выдает ошибку «отсутствует выражение».

update wr_rpt_group a
set a.rpt_category_id = 
case
  when (select c.control_plan from grpmisc c where 
    c.grp = a.grp and c.sect = a.sect or a.sect in ('ALL','*'))
    then decode(c.control_plan, '01', '201', '02', '202', '03', '203', '93')
      else '93'
  end      
where a.rpt_category_id = '93';

Спасибо! * * 1004

Ответы [ 3 ]

0 голосов
/ 16 сентября 2011

Причина, по которой вы получаете ошибку, состоит в том, что у вас есть выражение регистра без оператора.Oracle не знает, что делать с этим запросом в операторе case (и я тоже не знаю): вы пытаетесь проверить существование?Вы ищете конкретное значение?

Кроме того, глупо и сбивает с толку (не говоря уже о ненужном, в данном случае) использовать как case, так и decode в одном выражении.Я думаю, что вы хотели, чтобы это было:

UPDATE wr_rpt_group a
SET    a.rpt_category_id   =
          CASE (SELECT c.control_plan
                FROM   grpmisc c
                WHERE  c.grp = a.grp 
                  AND  c.sect = a.sect 
                   OR  a.sect IN ('ALL', '*'))
             WHEN '01' THEN '201'
             WHEN '02' THEN '202'
             WHEN '03' THEN '203'
             ELSE '93'
          END
WHERE  a.rpt_category_id = '93';

Наконец, я был бы очень осторожен, смешивая and и or, не добавляя еще несколько скобок.Сейчас я думаю, что ваш запрос будет оценен как c.grp_ = a.grp and (c.sect = a.sect or a.sect in ('ALL','*')), но я просто не уверен.Всегда лучше добавить скобки, а не полагаться на память о порядке прецедентов.

0 голосов
/ 18 сентября 2011

О скобках: И имеет более высокий приоритет, чем ИЛИ, таким образом, данный запрос оценивается как

(c.grp_ = a.grp and c.sect = a.sect)
or
a.sect in ('ALL','*')

, что, на мой взгляд, не предназначено.По крайней мере, брекетинг как

c.grp_ = a.grp
and
( c.sect = a.sect or a.sect in ('ALL','*'))

имеет больше смысла для меня.

Или даже лучше:

c.grp_ = a.grp
and
a.sect in ('ALL','*',c.sect)
0 голосов
/ 16 сентября 2011

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

update wr_rpt_group a
set a.rpt_category_id = select decode(c.control_plan, 
                                      '01', '201', 
                                      '02', '202', 
                                      '03', '203', 
                                      '93') 
                        from grpmisc c 
                        where c.grp = a.grp 
                        and c.sect = a.sect 
                        or a.sect in ('ALL','*'))
where a.rpt_category_id = '93'
and   exists (select 1
          from grpmisc c 
          where c.grp = a.grp 
          and c.sect = a.sect 
          or a.sect in ('ALL','*'))

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

and   1 in (select count(1)
          from grpmisc c 
          where c.grp = a.grp 
          and c.sect = a.sect 
          or a.sect in ('ALL','*'))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...