2010-05-24 2 views
4

Я хочу обновить запись в таблице, но на основе условия я либо обновляю один столбец, либо не хочу иметь 2 отдельных оператора, потому что инструкции очень длинный и подробный.Oracle - обновление одного столбца на основе условия

Вот основная идея с упрощением, чтобы добраться до точки.

PROCEDURE Animal_something(p_updater VARCHAR2) 

begin 

    if p_updater = 'person' then 
    -- I want to update the modified_by 
    else 
    -- if p_updater = 'a process' I want to update modified_by_process 

Update table_creatures 
    set animal_type = 'Dog , 

**modified_by** = 'Bob' 
**or do this** 
**modified_by_process =** 'creature_package' 

where animal_legs = '4' 

Я не хочу:

if p_updater = 'person' then 
    Update table_creatures 
    set animal_type = 'Dog , 
     modified_by = 'Bob' 
    where animal_legs = '4'; 
else 

    Update table_creatures 
    set animal_type = 'Dog , 
     modified_by_process = 'creature_package' 
    where animal_legs = '4'; 

end; 

ответ

6
UPDATE table_creatures 
SET  animal_type = 'Dog', 
     modified_by = CASE p_updater WHEN 'person' THEN 'Bob' ELSE modified_by END, 
     modified_by_process = CASE p_updater WHEN 'process' THEN 'creature_package' ELSE modified_by_process END 
WHERE animal_legs = 4 
+0

+1, избивайте меня :) –

0

Вы можете использовать динамический SQL, например:

PROCEDURE Animal_something(p_updater VARCHAR2) 

    sql_string_pt1 VARCHAR2(2000) := 'UPDATE table_creatures SET animal_type = :1'; 
    sql_string_pt2 VARCHAR2(2000) := NULL; 
    sql_string_pt3 VARCHAR2(2000) := ' WHERE animal_legs = :3'; 

begin 

    if p_updater = 'person' then 
    sql_string_pt2 := ', modified_by = :2'; 
    else 
    sql_string_pt2 := ', modified_by_process = :2'; 
    end if; 

    EXECUTE IMMEDIATE sql_string_pt1 || sql_string_pt2 || sql_string_pt3 
    USING 'Dog', 'Bob', '4'; 

end; 

Это имеет два преимущества по сравнению с ответом Quassnoi в: использование связывать переменные и не нужно обновлять оба столбца при каждом выполнении, что приведет к повторному повторению хотя фактическое значение не изменяется.

С другой стороны, утверждение не проверяется вообще во время компиляции.

+0

А? Литералы - это литералы, им не нужно быть «БОЙНЫ». По своей природе они НЕ ИЗМЕНЯЮТСЯ от исполнения до исполнения. И я уверен, что он предназначался для всего, что изменится, чтобы быть измененным на переменную в коде z-dan, и она будет проверена. –

+0

Я никогда не использовал ничего подобного, очень крутой подход, я мог бы попробовать это. Хотя, мне интересно с длинным оператором обновления, если это лучший способ кодирования с точки зрения обслуживания. –

+0

@Page: вы, вероятно, правы, но я склоняюсь к подходу Коста, то есть, если вопросник задает такой вопрос, скорее всего, они не знают разницы между использованием литералов и переменных привязки, так что это хорошая идея для иллюстрации лучшей практики. «Собака», «Боб» и «4» кажутся хорошими кандидатами на переменные. @ z-dan: динамический SQL - это компромисс между гибкостью и ремонтопригодностью, хотя есть способы упростить обнаружение ошибок (например, использование шаблона с заменой токенов вместо объединения бит-бит разных частей SQL). –

-1
UPDATE table_creatures 
SET  animal_type = 'Dog', 
     modified_by = DECODE(p_updater , 'person' , 'BOB' , 
             'proces' , 'creature_package' , 
             'GIVE DEFAULT VALUE')   
WHERE animal_legs = 4; 

Вы можете попробовать это.

+1

Он хочет обновить другой * столбец * на основе значения 'p_updater', а не просто обновить' modified_by' с другим значением. –

+0

Если p_updater - это столбец в table_creatures, тогда над запросом будет работать. Этот запрос обновлялся modified_by на основе значения p_updater – Bharat

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