在日常开发中我们往往会遇到各种各样的问题,有些问题还是值得记录下来,多积累才会成长。
在日常开发测试过程中,遇到程序报错,提示记录或者表被锁定,无法更新,遇到这种情况往往就是我们相关联的表被锁定了,引起表锁定的原因有多种,比如数据库连接打开了没有关闭;开启了手动事物监听,但是在程序执行报错时,catch{}内没有进行回滚;或者在手动操作数据库某条记录,使用for update没有提交等等都会引起数据库锁表,表锁住了程序就会卡死在这里,这个时候我们就要把锁表这个进程给杀掉,释放它。 具体操作如下:
--执行下面这条sql 查询出来如果有值 那么就是被锁的进程 select t2.username, t2.sid, t2.serial#, t3.object_name, t2.OSUSER, t2.MACHINE, t2.PROGRAM, t2.LOGON_TIME, t2.COMMAND, t2.LOCKWAIT, t2.SADDR, t2.PADDR, t2.TADDR, t2.SQL_ADDRESS, t1.LOCKED_MODE from v$locked_object t1, v$session t2, dba_objects t3 where t1.session_id = t2.sid and t1.object_id = t3.object_id order by t2.logon_time; --把SID 和SERIAL#复制出来 扔到下面session里 执行一下 搞定 alter system kill session 'sid, serial; --查询造成锁定的sql SELECT /*+ ORDERED */ sql_text FROM v$sqltext a WHERE (a.hash_value, a.address) IN (SELECT DECODE(sql_hash_value, 0, prev_hash_value, sql_hash_value), DECODE(sql_hash_value, 0, prev_sql_addr, sql_address) FROM v$session b WHERE b.sid = '1286') /* 此处为SID*/ ORDER BY piece ASC;可能这种情况大家都遇到过,在操作某一条数据时,因为写sql时候的大意,误删或者误修改了其他数据,而这个时候又没有备份,或者备份的版本时间太久,不能确定与当前数据是否具有一致性,那么这个时候就可以使用数据库自带的闪回备份功能,可以寻找半小时内被误操作的数据,再通过备份来还原。 具体操作如下:
--比如现在时间是10月1号12:30,这条sql可以查询到12点这个时间段,表A内的数据状况: select * from 表A as of timestamp to_timestamp('2019-10-01 12:00:00','yyyy-mm-dd hh24:mi:ss'); --如果需要对这个时间段的表数据备份的话: create table 备份表B as select * from 表A as of timestamp to_timestamp('2019-10-01 12:00:00','yyyy-mm-dd hh24:mi:ss');我们都知道通过sql修改一条数据的话,直接update就完事了,如果我们遇到多表联合批量刷新该怎么办,每一个字段所获取对应的值都不一样,需要从其他表拿过来,使用关联字段进行批量刷新,有人会说写存储过程,的确,如果是在程序中,肯定使用这种办法,因为游标效率低,但是如果是临时处理数据的话,游标往往比写存储过程来的快。 具体操作如下:
--tableno 学号 tablevalue 成绩 tabletype 类别 begin for cr in (select a.tableno,b.tablevalue from 表A a,表B b where a.id = b.tableid and a.tabletype='学生') loop update 表C p set p. tablevalue = cr. tablevalue where p. tableno = cr. tableno; end loop; end;