一.背景
半路接手项目,文档资料不全。希望整清楚整个系统有哪些表的字段用了哪些sequence。运维中,oracle导入后出现过sequence的值比数据表里面的值小,原因不详。希望自动把所有sequence都检查一遍。
二.关键sql
可以查询出所有的表名字、字段名字、触发器名字。
SELECT
s.tname,
s.cname,
s.qname
FROM
(
SELECT
c.table_name AS tname,
A .sequence_name AS qname,
SUBSTR (
b.text,
INSTR (LOWER(b.text), ':new.') + 5,
INSTR (LOWER(b.TEXT), 'from') - INSTR (LOWER(b.text), ':new.') - 5
) AS cname
FROM
(
SELECT
sequence_name
FROM
user_sequences
) A,
(
SELECT
text,
NAME
FROM
user_source
WHERE
TYPE = 'TRIGGER'
) b,
(
SELECT
table_name,
TRIGGER_name
FROM
user_triggers
) c
WHERE
c.TRIGGER_name = b. NAME
AND UPPER(b.text) LIKE '%' || upper(A .sequence_name) || '%' --精髓,oracle有些sequence创建名称是小写,但是数据库里面名称是大写
ORDER BY
table_name ASC
) s
WHERE
s.cname IS NOT NULL
开发了一个小的应用,思路是遍历前面sql结果。逐一去查sequence的当前值与表中字段最大值比较,如果不大于,就处理sequence的值。处理的方法就是先把sequence的增长步长修改为差值+1,查询一次。再把sequence的步长修改为1。
主要sql如下:
1. 查询业务表
select nvl(max(ID ),0) from APP_MATERIAL
2.查询sequence
select SEQ_APP_MATERIAL.NEXTVAL from Dual
3.修改步长为差值
alter sequence SEQ_APP_MATERIAL increment by 78
4.再查询一次
select SEQ_APP_MATERIAL.NEXTVAL from Dual
5.修改步长为1
alter sequence SEQ_APP_MATERIAL increment by 1