2017-01-25 4 views
0

Я пытаюсь переключить значение на основе набора условий, и я заметил, что там, где у меня есть вложенный оператор CASE в предложении SET моего выражения UPDATE, столбцы не обновляются.Вложенный оператор CASE в предложении UPDATE SET

Когда существует простое выражение CASE, столбцы, по-видимому, обновляются. Однако для OVERRIDDEN_CHECK_NUMBER и OVERRIDDEN_AMOUNT в этом примере столбцы не обновляются.

Столы OVERRIDDEN_DATE, OVERRIDDEN_USER_ID, CHECK_NO и AMOUNT в UPDATE обновляются без проблем.

Может ли кто-нибудь сказать мне, почему OVERRIDDEN_CHECK_NUMBER и OVERRIDDEN_AMOUNT не будут обновляться в этой инструкции UPDATE?

Являются ли вложенные операторы CASE не слагаемыми в предложении SET выражения UPDATE?

SQL Пример

UPDATE WAREHOUSE.BANK_STATEMENT_ACTIVITY 
    SET OVERRIDDEN_CHECK_NO  = --(CASE :btn           
             (CASE WHEN (:btn = '1') THEN CASE WHEN '141973' = '141973' THEN NULL 
                      WHEN '141973' != '999999' THEN LPAD(TRIM(141973), 12, '0') 
                     END 
             WHEN (:btn = '2') THEN '1740 - Previously Paid Warrant' 
             ELSE NULL 
            END), 
     OVERRIDDEN_AMOUNT   = --(CASE :btn 
             (CASE WHEN (:btn = '1') THEN CASE WHEN 253.20 = 253.20 THEN NULL 
                      WHEN 253.20 != 999.99 THEN LPAD(TRIM(253.20), 12, '0') 
                     END 
             WHEN (:btn = '2') THEN NULL 
             ELSE NULL 
            END), 
     OVERRIDDEN_DATE   = SYSDATE, 
     OVERRIDDEN_USER_ID  = 1009, 
     CHECK_NO     = (CASE :btn 
             WHEN '1' THEN LPAD(TRIM(999999), 12, '0') 
             WHEN '2' THEN '142775' 
             ELSE NULL 
             END), 
     AMOUNT     = (CASE :btn 
             WHEN '1' THEN TRIM(78.60) 
             WHEN '2' THEN TRIM(253.20) 
             ELSE NULL 
             END) 
     WHERE TO_NUMBER(CHECK_NO) = (CASE :btn 
             WHEN '1' THEN '141973' 
             WHEN '2' THEN '142775' 
             ELSE NULL 
            END) 
     AND AMOUNT    = (CASE :btn 
             WHEN '1' THEN 78.60 
             WHEN '2' THEN 253.20 
             ELSE NULL 
            END) 
     AND TRUNC(LOAD_DATE)  = (CASE :btn 
             WHEN '1' THEN TRUNC(LOAD_DATE) 
             WHEN '2' THEN (SELECT (MAX(LOAD_DATE)) FROM WAREHOUSE.BANK_STATEMENT_ACTIVITY) 
             ELSE NULL 
             END) 
     AND BANKACCTNO   = (SELECT LONGDESC 
            FROM TCMS.COMPLEMENTARY_VALIDATIONS 
            WHERE TEXTCODE = 'BANKACCT' 
            AND CODE = 80); 

EDIT

После фиксации logival вопрос, который @mathguy указал, запрос обновления с помощью редактора работал. Тем не менее, при выполнении этого с помощью PLAC SQL/Pacakge обновление таблицы не выполняется.

Вот перед обновлением:

Before - result

Ее это после того, как результат:

After - result

Они идентичны.

Это фактическая процедура пакета:

PROCEDURE UpdateBankStatementActivity(btn IN VARCHAR2) 
AS 
BEGIN 
DBMS_OUTPUT.PUT_LINE('UpdateBankStatementActivity - btn: ' || btn); 
DBMS_OUTPUT.PUT_LINE('UpdateBankStatementActivity - bsa_rec.OVERRIDDEN_CHECK_NO: ' || bsa_rec.OVERRIDDEN_CHECK_NO || CHR(10) || 
                'bsa_rec.OVERRIDDEN_AMOUNT: ' || bsa_rec.OVERRIDDEN_AMOUNT || CHR(10) || 
                'bsa_rec.CHECK_NO: ' || bsa_rec.CHECK_NO || CHR(10) || 
                'bsa_rec.AMOUNT: ' || bsa_rec.AMOUNT || CHR(10) || 
                'bsa_rec.LOAD_DATE:' || bsa_rec.LOAD_DATE); 
    UPDATE WAREHOUSE.BANK_STATEMENT_ACTIVITY 
    SET OVERRIDDEN_CHECK_NO  = --(CASE :btn           
             (CASE WHEN (btn = '1') THEN CASE WHEN bsa_rec.OVERRIDDEN_CHECK_NO = bsa_rec.CHECK_NO THEN NULL 
                     WHEN bsa_rec.OVERRIDDEN_CHECK_NO != bsa_rec.CHECK_NO THEN LPAD(TRIM(bsa_rec.OVERRIDDEN_CHECK_NO), 12, '0') 
                    END 
             WHEN (btn = '2') THEN '1740 - Previously Paid Warrant' 
             ELSE NULL 
            END), 
     OVERRIDDEN_AMOUNT   = --(CASE :btn 
             (CASE WHEN (btn = '1') THEN CASE WHEN bsa_rec.OVERRIDDEN_AMOUNT = bsa_rec.AMOUNT THEN NULL 
                     WHEN bsa_rec.OVERRIDDEN_AMOUNT != bsa_rec.AMOUNT THEN LPAD(TRIM(bsa_rec.OVERRIDDEN_AMOUNT), 12, '0') 
                    END 
             WHEN (btn = '2') THEN NULL 
             ELSE NULL 
            END), 
     OVERRIDDEN_DATE   = SYSDATE, 
     OVERRIDDEN_USER_ID  = bsa_rec.OVERRIDDEN_USER_ID, 
     CHECK_NO     = (CASE btn 
             WHEN '1' THEN LPAD(TRIM(bsa_rec.CHECK_NO), 12, '0') 
             WHEN '2' THEN LPAD(TRIM(bsa_rec.CHECK_NO), 12, '0') 
             ELSE NULL 
             END), 
     AMOUNT     = (CASE btn 
             WHEN '1' THEN TRIM(bsa_rec.OVERRIDDEN_AMOUNT) 
             WHEN '2' THEN TRIM(bsa_rec.AMOUNT) 
             ELSE NULL 
             END) 
     WHERE TO_NUMBER(CHECK_NO) = (CASE btn 
             WHEN '1' THEN bsa_rec.OVERRIDDEN_CHECK_NO 
             WHEN '2' THEN bsa_rec.CHECK_NO 
             ELSE NULL 
            END) 
     AND AMOUNT    = (CASE btn 
             WHEN '1' THEN bsa_rec.OVERRIDDEN_AMOUNT 
             WHEN '2' THEN bsa_rec.AMOUNT 
             ELSE NULL 
            END) 
     AND TRUNC(LOAD_DATE)  = (CASE btn 
            WHEN '1' THEN TRUNC(bsa_rec.LOAD_DATE) 
            WHEN '2' THEN (SELECT MAX(LOAD_DATE) FROM WAREHOUSE.BANK_STATEMENT_ACTIVITY) 
            ELSE NULL 
            END) 
     AND BANKACCTNO   = (SELECT LONGDESC 
            FROM TCMS.COMPLEMENTARY_VALIDATIONS 
            WHERE TEXTCODE = 'BANKACCT' 
            AND CODE = 80); 

    COMMIT; 
END UpdateBankStatementActivity; 

Значения параметров в первом фрагменте кода SQL согласуются с параметрами в/SQL блок PL.

+0

Я считаю, что это должно сработать. Можете ли вы отправить пример с данными перед обновлением, запуском обновления (включая значения переменных) и данными после обновления. Я считаю, что одного единственного нерабочего столбца было бы достаточно, чтобы объяснить этот вопрос. – Aleksej

+0

mathguy указал на ошибку в логике, которую я исправил, и обновление работает через редактор. Однако при выполнении через пакет таблица не обновляется ... Я приведу примеры как можно скорее. – TheSchnitz

+0

@TheSchnitz - убедитесь, что вы изменили код в процедуре в пакете и перекомпилируете все. В противном случае Oracle по-прежнему будет использовать «последнюю известную хорошую» версию! – mathguy

ответ

1

Что вы подразумеваете под "не обновлением"?

Существует явный логический недостаток в ваших вложенных выражениях case, когда :btn = '1'. А именно, первая ветвь «внутреннего» выражения case всегда имеет значение TRUE, поэтому «значение обновления» будет null каждый раз, когда вы передаете :btn = '1'. Это проблема, которую вы замечаете? Тогда: для overridden_amount результат всегда будет null из-за этого; для overridden_check_no это не будет null если и только если :btn = '2'.

Обратите внимание, что вы можете написать выражения «внешний» case с тем же синтаксисом, который вы используете для простых выражений: case :btn when '1' then case .... end else ... end.

EDIT: Отвечая на ваш измененный вопрос (возможно).Я не уверен, что могу полностью следовать логике; но то, что происходит в примере (если вы назвали процедуру btn = '1' заключается в следующем:.

И overridden_check_no и overridden_amount находятся в исходной таблице null В вложенной (внутренней) case выражения для обеих колонок вы проверяете две колонки , либо с = или !=. ни из испытаний true, когда один из слагаемых null! Так case оценки проваливается к статье else, или когда else не включена, по умолчанию, который null. The update фактически сделал произведение, это просто обновление ed значениями null, потому что ни одна из «фактических ветвей» во внутренних операциях case оценивается как true.

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

+0

Спасибо, что указал. Сказав это, когда я тестирую это в редакторе, он обновляет таблицу, но когда я выполняю это через свой пакет PL/SQL, таблица не обновляется. – TheSchnitz

+0

Я чувствую себя смущенным. Я только что нашел свою ошибку. В моей тестовой процедуре я проходил неправильную сумму, которая в основном делала предложение WHERE неправильным для обновления конкретной тестовой записи. Большое вам спасибо за вашу помощь! Извиняюсь. – TheSchnitz

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