【发布时间】:2017-06-10 21:25:26
【问题描述】:
我正在尝试根据一组条件切换一个值,我注意到在我的 UPDATE 表达式的 SET 子句中有一个嵌套的 CASE 语句时,列没有更新。
当存在简单的 CASE 表达式时,列似乎正在更新。但是,对于本示例中的 OVERRIDDEN_CHECK_NUMBER 和 OVERRIDDEN_AMOUNT,列不会更新。
UPDATE 中的 OVERRIDDEN_DATE、OVERRIDDEN_USER_ID、CHECK_NO 和 AMOUNT 列正在更新,没有问题。
谁能告诉我为什么 OVERRIDDEN_CHECK_NUMBER 和 OVERRIDDEN_AMOUNT 不会在这个 UPDATE 语句中更新?
在 UPDATE 表达式的 SET 子句中是否没有嵌套 CASE 语句?
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 包执行此操作时,表更新失败。
这是更新前的内容:
她是后来的结果:
它们是相同的。
这是实际的打包过程:
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 sn -p中的参数值与PL/SQL块中的参数一致。
【问题讨论】:
-
我相信这应该可行。您能否发布一个示例,其中包含更新前的数据、更新运行(包括变量值)和更新后的数据。我相信一个不工作的专栏就足以解释这个问题。
-
mathguy 指出了我纠正的逻辑中的一个错误,并且通过编辑器进行了更新。但是,通过包执行时,表格没有更新……我会尽快提供示例。
-
@TheSchnitz - 确保更改包中过程中的代码,然后重新编译所有内容。否则 Oracle 仍将使用“最后已知的良好”版本!
-
谢谢@mathguy。每次通过包执行时,我都在重新编译和查看表数据。
-
我已经添加了请求的信息和一些附加信息。感谢您的帮助!
标签: sql oracle sql-update case