版本
准生产环境,5.7.25-OceanBase_CE-v4.3.5.5
问题
在oceanbase update语句中依赖会话变量做排序计数未生效(修改update语句格式后能正常更新),该sql在mysql中行为正常
Your MySQL connection id is 607220
Server version: 5.6.25 OceanBase_CE 4.3.5.5
SELECT * FROM `test_session_variable` where xx_id in(3741066) limit 5;
+-----+---------+---------+
| id | xx_code | xx_id |
+-----+---------+---------+
| 208 | 208 | 3741066 |
| 209 | 209 | 3741066 |
| 210 | 210 | 3741066 |
| 211 | 211 | 3741066 |
| 212 | 212 | 3741066 |
+-----+---------+---------+
5 rows in set (0.00 sec)
#分别在oceanbase和mysql执行下面update 进行排序计数
update
test_session_variable it
set
it.xx_id = 3741066,
it.xx_code =
(
select @rownum := @rownum + 10 as rownum
from
(select @rownum := 66670 ) r, (select t.id from test_session_variable t where xx_id in(3741066)) temp
where temp.id = it.id
)
where it.xx_id in (3741066);
| oceanbase xx_code未被更新 | mysql xx_code被正确更新 |
|---|---|
![]() |
![]() |
临时修改update语句格式后能正常更新
update
test_session_variable it
CROSS JOIN (select @rownum := 66670) r
set
it.xx_id = 3741066,
it.xx_code = (@rownum := @rownum + 10)
where it.xx_id in (3741066);
SELECT * FROM `test_session_variable` where xx_id in(3741066) limit 20;
+-----+---------+---------+
| id | xx_code | xx_id |
+-----+---------+---------+
| 208 | 66680 | 3741066 |
| 209 | 66690 | 3741066 |
| 210 | 66700 | 3741066 |
| 211 | 66710 | 3741066 |
| 212 | 66720 | 3741066 |
| 213 | 66730 | 3741066 |
| 214 | 66740 | 3741066 |
| 215 | 66750 | 3741066 |
| 216 | 66760 | 3741066 |
| 217 | 66770 | 3741066 |
分析
第一个update中仅是select子句查排序计数会话变量是正常
mysql> select @rownum := @rownum + 10 as rownum
-> from
-> (select @rownum := 66670 ) r, (select t.id from test_session_variable t where xx_id in(3741066)) temp
-> ;
+--------+
| rownum |
+--------+
| 66680 |
| 66690 |
| 66700 |
| 66710 |
| 66720 |
| 66730 |
| 66740 |
| 66750 |
| 66760 |
当加上了update set语句,应该出现了行为变化,这子句只执行了一次 select @rownum := @rownum + 10 as rownum
it.xx_code =
(
select @rownum := @rownum + 10 as rownum
from
(select @rownum := 66670 ) r, (select t.id from test_session_variable t where xx_id in(3741066)) temp
where temp.id = it.id
)
临时修改后的update语句,应该先笛卡尔积关联生成了“临时表”,再set逐行更新
test_session_variable it
CROSS JOIN (select @rownum := 66670) r
set
it.xx_code = (@rownum := @rownum + 10)
复现
CREATE TABLE `test_session_variable` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`xx_code` int(11) DEFAULT NULL,
`xx_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO `test_session_variable` (`id`,`xx_code`,`xx_id`) VALUES (208,208,3741066);
INSERT INTO `test_session_variable` (`id`,`xx_code`,`xx_id`) VALUES (209,209,3741066);
INSERT INTO `test_session_variable` (`id`,`xx_code`,`xx_id`) VALUES (210,210,3741066);
INSERT INTO `test_session_variable` (`id`,`xx_code`,`xx_id`) VALUES (211,211,3741066);
INSERT INTO `test_session_variable` (`id`,`xx_code`,`xx_id`) VALUES (212,212,3741066);
INSERT INTO `test_session_variable` (`id`,`xx_code`,`xx_id`) VALUES (213,213,3741066);
INSERT INTO `test_session_variable` (`id`,`xx_code`,`xx_id`) VALUES (214,214,3741066);
INSERT INTO `test_session_variable` (`id`,`xx_code`,`xx_id`) VALUES (215,215,3741066);
INSERT INTO `test_session_variable` (`id`,`xx_code`,`xx_id`) VALUES (216,216,3741066);
INSERT INTO `test_session_variable` (`id`,`xx_code`,`xx_id`) VALUES (217,217,3741066);
INSERT INTO `test_session_variable` (`id`,`xx_code`,`xx_id`) VALUES (218,218,3741066);
INSERT INTO `test_session_variable` (`id`,`xx_code`,`xx_id`) VALUES (219,219,3741066);
INSERT INTO `test_session_variable` (`id`,`xx_code`,`xx_id`) VALUES (220,220,3741066);
INSERT INTO `test_session_variable` (`id`,`xx_code`,`xx_id`) VALUES (221,221,3741066);
INSERT INTO `test_session_variable` (`id`,`xx_code`,`xx_id`) VALUES (222,222,3741066);
INSERT INTO `test_session_variable` (`id`,`xx_code`,`xx_id`) VALUES (223,223,3741066);
INSERT INTO `test_session_variable` (`id`,`xx_code`,`xx_id`) VALUES (224,224,3741066);
INSERT INTO `test_session_variable` (`id`,`xx_code`,`xx_id`) VALUES (225,225,3741066);
INSERT INTO `test_session_variable` (`id`,`xx_code`,`xx_id`) VALUES (226,226,3741066);
INSERT INTO `test_session_variable` (`id`,`xx_code`,`xx_id`) VALUES (227,227,3741066);
...
update
test_session_variable it
set
it.xx_id = 3741066,
it.xx_code =
(
select @rownum := @rownum + 10 as rownum
from
(select @rownum := 66670 ) r, (select t.id from test_session_variable t where xx_id in(3741066)) temp
where temp.id = it.id
)
where it.xx_id in (3741066);

