存储过程和sql窗口执行更新操作结果不一样的问题

在测试存储过程中,发现一个UPDATE语句在存储过程内更新了8条数据,但直接在SQL窗口执行只更新了1条。问题出在存储过程中的变量命名与表字段名相同,导致Oracle将某些条件视为恒等式,忽略了相应的WHERE子句。解决方案是将变量名改得与表字段名不同,如改为V_COLUMN_3等,从而避免混淆,使得存储过程正确地仅更新1条记录。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

写了一个存储过程,需要更新一张表的数据,存储过程中的sql如下:

 UPDATE TABLE_A T

       SET T.COLUMN_1 = IN_RECORD_ID, T.COLUMN_2= '1'

     WHERE T.COLUMN_3 = COLUMN_3(存储过程执行中为0000474203

       AND T.COLUMN_4 = COLUMN_4(存储过程执行中为200707

       AND T.COLUMN_5 = COLUMN_5(存储过程执行中为2

       AND T.COLUMN_6 = COLUMN_6(存储过程执行中为0

       AND T.COLUMN_7 = COLUMN_7(存储过程执行中为1

       AND T.COLUMN_8 = COLUMN_8(存储过程执行中为0

       AND T.COLUMN_9 = CHARGE_NO;(存储过程执行中为0000474203

 

其中where条件后面的都是变量。

在测试过程中发现,本来这个语句只应该更新一条数据,但是执行结果却是更新了8条,我以为是我写的where条件不够精确,导致这个sql找到了8条需要更新的数据,所以我把sql单独复制出来到sql窗口中执行,并把上面的变量转换为我执行存储过程中的相同变量,结果sql语句执行只更新了1条,sql如下:

UPDATE TABLE_A T

       SET T.COLUMN_1 = '18820131026000000012', T.COLUMN_2= '1'

     WHERE T.COLUMN_3 = '0000474203'

       AND T.COLUMN_4= '200707'

       AND T.COLUMN_5 = '2'

       AND T.COLUMN_6 = '0'

       AND T.COLUMN_7 = '1'

       AND T.COLUMN_8 = '0'

       AND T.COLUMN_9 = '0000474203';

 

 

这让我百思不得其解,只能求助于其他同事,过程咱就不说了,说说最后错误是在哪吧。

sql窗口中的sql与存储过程中的sql最大的区别在于sql窗口中的sql我们用真正的值(即COLUMN_30000474203这些值),而存储过程中的sql是变量,在仔细看看这个变量的名字,跟我们要更新的这个表的字段名字是一样的(除了COLUMN_9外,后面会解释),那oracle就认为这是一个恒等式,t.COLUMN_3=COLUMN_3是没有意义的,所以它执行的更新sql的条件其实就只有t.COLUMN_9= '0000474203',而这个条件定位的就有8条记录,所以全部被更新了。

结果我立刻将这些变量换个名字,更新sql修改为:

UPDATE TABLE_A T

       SET T.COLUMN_1 = IN_RECORD_ID, T.COLUMN_2= '1'

     WHERE T.COLUMN_3 = V_COLUMN_3(存储过程执行中为0000474203

       AND T.COLUMN_4 = V_COLUMN_4(存储过程执行中为200707

       AND T.COLUMN_5 = V_COLUMN_5(存储过程执行中为2

       AND T.COLUMN_6 = V_COLUMN_6(存储过程执行中为0

       AND T.COLUMN_7 = V_COLUMN_7(存储过程执行中为1

       AND T.COLUMN_8 = V_COLUMN_8(存储过程执行中为0

       AND T.COLUMN_9 = V_CHARGE_NO;(存储过程执行中为0000474203

再次执行存储过程,一切ok了,只更新了一条,我也不知道oracle这个机制是咋回事,以后慢慢琢磨吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值