生成测试数据,房间号数据如下:
CREATE TABLE hotel (floor_nbr,room_nbr) ASSELECT 1,100 FROM DUAL UNION ALLSELECT 1,100 FROM DUAL UNION ALLSELECT 2,100 FROM DUAL UNION ALLSELECT 2,100 FROM DUAL UNION ALLSELECT 3,100 FROM DUAL;
里面的房间号是不对的,一般是101、102、201、202的形式。现要求重新生成房间号,可以用 row_number 函数来更新数据,重新生成房间号。
update hotel set room_nbr = floor_nbr * 100 + row_number() over(partition by floor_nbr order by rownum);
ORA-30483: window 函数在此禁用
试试看“可更新VIEW”
update (select room_nbr,floor_nbr * 100 + row_number() over(partition by floor_nbr order by rowid) as new_nbrfrom hotel)set room_nbr = new_nbr;
ORA-01732: 此视图的数据操纵操作非法
update再嵌套一层倒是可以实现:
update hotel aset room_nbr = (select room_nbrfrom (select floor_nbr * 100 + row_number() over(partition by floor_nbr order by rowid) as room_nbrfrom hotel) bwhere a.rowid = b.rowid);
select * from hotel;
试试 merge into 的方式,也可以:
merge into hotel ausing (select rowid as rid,floor_nbr * 100 + row_number() over(partition by floor_nbr order by rowid) as room_nbrfrom hotel) bon (a.rowid = b.rid)when matched thenupdate set a.room_nbr = b.room_nbr;
可以看到,使用update嵌套更新的方式,子查询全表扫描要5次;但是merge into,子查询只需要全表扫描一次。