我试图根据一组条件切换一个值,我注意到在我的UPDATE表达式的SET子句中有一个嵌套的CASE语句,列没有更新。
当存在简单的CASE表达式时,列似乎正在更新。但是,对于此示例中的OVERRIDDEN_CHECK_NUMBER和OVERRIDDEN_AMOUNT,列不会更新。
UPDATE中的OVERRIDDEN_DATE,OVERRIDDEN_USER_ID,CHECK_NO和AMOUNT列正在更新而不会出现问题。
有谁可以告诉我为什么OVERRIDDEN_CHECK_NUMBER和OVERRIDDEN_AMOUNT不会在此UPDATE语句中更新?
嵌套的CASE语句是否在UPDATE表达式的SET子句中没有用?
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);
修改
修复了@mathguy通过编辑器指出更新查询的逻辑问题。但是,当通过PL / SQL pacakge执行此操作时,表更新失败。
以下是更新前的内容:
她的结果是:
它们完全相同。
这是实际的套餐程序:
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 CODE代码段中的参数值与PL / SQL块中的参数一致。
答案 0 :(得分: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
。
编辑:回答您修改后的问题(可能)。我不确定我是否可以完全遵循逻辑;但是示例中发生了什么(假设您使用btn = '1'
调用过程是这样的:
原始表格中overridden_check_no
和overridden_amount
都是null
。在两列的嵌套(内部)case
表达式中,您可以检查两列,其中包含=
或!=
。 如果其中一个条款为true
,那么1>的测试都不是null
!因此,case
评估会转到else
子句,或者不包括else
时,默认值为null
。 update
实际上确实有效,它只是将值更新为null
,因为没有一个"实际分支"在评估为case
的内部true
语句中。
但是,如果您只是直接从编辑器中将其作为独立的SQL update
运行,那么您可以这样说。我想知道这是怎么可能的,除非 - 再次 - 程序中的代码与编辑器中的代码不同。