转://批量更新sequence的存储
|
--批量更新序列存储--
CREATE OR REPLACE PROCEDURE P_SYNCSEQ(USERNAME VARCHAR2 /*传入要检查/更新序列的用户*/ ) IS /*
**@AUTHOR 毛海晴
ORACLE 批量更新SEQUENCE
注释:
批量更新SEQUENCE,
更新序列下一个值 = 主键最大值+1
---序列创建时,属性NOMAXVALUE=最大值是10的28次方
思路:
1、找到每个表主键列 且在该表主键最大值是什么?
2、找到表对应SEQUENCE值 与 表主键最大值去对比。
如果SEQUENCE
下一个值大于表主键最大值就不做更新; 否则需要进行更新(2中更新方式)
1)删除SEQUENCE ,创建新序列开始值为表主键最大值+1;
--本文选择此方案...嘿嘿~ (坏处:赶好在DROP
SEQUENCE..而程序也恰巧调用依赖它的函数和存储过程将失效 但 后续CREATE SEQUENCE了,再调用了会重新编译
调用..不会报错....有实验过哦~) 2)ALTER SEQUENCE .. INCREMENT BY ..
NOCACHE; SELECT ...NEXTVAL FROM DUAL;
ALTER SEQUENCE .. INCREMENT BY 1 CACHE
20; ....
sequence.nextval其实也可以用user_sequences.last_number字段实现..由于最早存储就这样的写就没改~...谅解~ SEQUENCE和表名长度最大限制是30
SEQUENCE规范的名字SEQ_+表名字 -- 此处规范只是管理维护方便而已
并不是非要这样要求 如果表名长度大小大于26
加上"SEQ_"就大于了SEQUENCE长度限制的30 若表名长度大于26,那对应序列肯定不是规范命名(SEQ_表名字),再由于这样的序列并不多,所以将这些一一处理 在更新前可先注释掉EXECUTE IMMEDIATE,先作下测试看下效果,免得EXECUTE
IMMEDIATE DROP .后创建报错,导致在调用 序列不会创建,也校验不到序列 所需权限:
-- 创建序列权限 -- -- Grant/Revoke system privileges
grant create sequence to LOTTERY; --查询权限-- -- Grant/Revoke object privileges grant select on DBA_CONSTRAINTS to LOTTERY; grant select on DBA_CONS_COLUMNS to LOTTERY; grant select on DBA_SEQUENCES to LOTTERY; grant select on DBA_TABLES to LOTTERY; grant select on DBA_TAB_COLUMNS to LOTTERY; --或者-- -- Grant/Revoke system privileges grant select any dictionary to LOTTERY; */
--变量
MAX_ID NUMBER(12 );
P_SEQ_NUM NUMBER(12 );
P_TABLE_NAME VARCHAR2(50 );
P_COLUMN VARCHAR2(50 );
P_SEQUENCE VARCHAR2(50 );
P_SQL VARCHAR2(500 );
P_SEQ_SQL VARCHAR2(5000 );
P_SQL_SEQ VARCHAR2(30000 );
P_NEW_COUNT NUMBER(12 );
--查询表长度小于26 的表/序列
--游标
CURSOR C_CONS IS -- 查询表长度小于26 的表/序列
SELECT T1.TABLE_NAME TABLE_NAME,
T1.COLUMN_NAME COLUMN_NAME,
T1.SEQUENCE_NAME1 SEQUENCE_NAME
FROM ((SELECT C.TABLE_NAME,
CASE
WHEN C1.DATA_TYPE = 'NUMBER' THEN
C.COLUMN_NAME
ELSE
'TO_NUMBER(' || C.COLUMN_NAME || ')'
END COLUMN_NAME,
C.SEQUENCE_NAME1
FROM (SELECT C.TABLE_NAME,
C.COLUMN_NAME,
'SEQ_' || C.TABLE_NAME SEQUENCE_NAME1
FROM DBA_CONS_COLUMNS C --用户的约束对应的表列信息
WHERE C.OWNER = UPPER (USERNAME)
AND (C.CONSTRAINT_NAME, C.TABLE_NAME) IN
( SELECT S.CONSTRAINT_NAME, S.TABLE_NAME
FROM DBA_CONSTRAINTS S --用户的对象约束信息
WHERE S.OWNER = (UPPER (USERNAME))
AND S.CONSTRAINT_TYPE = 'P' /*CONSTRAINT_TYPE:
P:主键,R:外键,C:非空约束/CHECK;*/ ---若主键是由多字段'ID1,ID2',该查询会显示成2行分别为(T.ID1 SEQ_T和T.ID2
SEQ_T) )
--..一个序列被2个表/2字段共用...可以用如下方式进行
UNION
SELECT 'ETL_CS_CUST_INFO_MID' ,
'BATCH_NO', --若数据为VARCHAR类型需要TO_NUMBER转换来取MAX(字段)
'SEQ_ETL_CS_CUST_INFO_MID'
FROM DUAL) C,
DBA_TAB_COLUMNS C1
WHERE C1.OWNER = UPPER (USERNAME)
AND C1.COLUMN_NAME = C.COLUMN_NAME
AND C1.TABLE_NAME = C.TABLE_NAME)
/**
---提供表长度大于26 的表名字/序列
..再关联DBA_CONS_COLUMNS找到对应的主键字段..和表长度小于26部分的查询进行UNION ALL CS_BEAR_ALLOWANCE_AND_INJ_DET --->
SEQ_CS_BEAR_ALLOWANCE_INJ_DET CS_BEAR_ALLOWANCE_AND_INJ_DETS --->
SEQ_CS_BEAR_ALLOWANCE_INJ_DETS...等 */
UNION ALL (SELECT M1.TABLE_NAME, COLUMN_NAME,
M2.SEQUENCE_NAME FROM (SELECT LENGTH(C.TABLE_NAME) AA,
C.TABLE_NAME, C.COLUMN_NAME FROM DBA_CONS_COLUMNS C
WHERE C.OWNER = UPPER (USERNAME)
AND (C.CONSTRAINT_NAME, C.TABLE_NAME) IN
( SELECT S.CONSTRAINT_NAME, S.TABLE_NAME FROM DBA_CONSTRAINTS S
WHERE S.OWNER = UPPER (USERNAME)
AND S.CONSTRAINT_TYPE = 'P' )) M1 --如果不限制主键 可能找到NOT NULL的列
JOIN (SELECT TABLE_NAME, SEQUENCE_NAME
FROM (SELECT 'CS_BEAR_ALLOWANCE_AND_INJ_DET' TABLE_NAME,
'SEQ_CS_BEAR_ALLOWANCE_INJ_DET' SEQUENCE_NAME
FROM DUAL
UNION ALL
SELECT 'CS_BEAR_ALLOWANCE_AND_INJ_DETS' ,
'SEQ_CS_BEAR_ALLOWANCE_INJ_DETS'
FROM DUAL)) M2
ON M1.TABLE_NAME = M2.TABLE_NAME
WHERE AA > 26 )) T1,
DBA_SEQUENCES SQ, --(列出的序列是否在库中存在)
DBA_TABLES T --(列出的表是否在库中存在)..由于环境不同用到的序列可能也是不同的.若不加可能会报错
WHERE SQ.SEQUENCE_NAME =
T1.SEQUENCE_NAME1 AND T.TABLE_NAME = T1.TABLE_NAME
AND SQ.SEQUENCE_OWNER = UPPER (USERNAME)
AND T.OWNER = UPPER (USERNAME);
----------------------以上查询表/对应序列/主键字段
------------- ----------------------以下开始判断序列是否需要更新
------------- BEGIN
----------------------SEQUENCE判断更新语句
----------------------------- --~~注释:DBMS_OUTPUT.PUT_LINE(XX)是将这个结果或者查询显示出来
--EXECUTE IMMEDIATE XX; --执行XX的查询
--开始 SEQUENCE.nextval和主键最大值 做比较..
FOR P_C_CONS IN C_CONS LOOP
--利用C_CONS游标对应列值
P_TABLE_NAME := P_C_CONS.TABLE_NAME;
P_COLUMN := P_C_CONS.COLUMN_NAME;
P_SEQUENCE :=
P_C_CONS.SEQUENCE_NAME; ---每次循环都赋值0 ..
MAX_ID := 0;
--查询表主键中最大值
P_SQL := 'SELECT MAX(' || P_COLUMN || ') FROM ' || P_TABLE_NAME;
--USING MAX_ID
EXECUTE IMMEDIATE P_SQL
INTO MAX_ID;
-- 查询序列.nextval值
P_SEQ_SQL := 'SELECT ' || P_SEQUENCE || '.NEXTVAL FROM DUAL' ;
--USING P_SEQ_SQL
EXECUTE IMMEDIATE P_SEQ_SQL
INTO P_SEQ_NUM;
---SEQUENCE.nextval和主键最大值
做比较..(如果SEQUENCE.nextval<主键最大值,更新序列'drop-create') IF P_SEQ_NUM < MAX_ID THEN
/*DBMS_OUTPUT.PUT_LINE( 'DROP SEQUENCE ' || P_SEQUENCE);*/
--删除原来不正确的SEQUENCE
EXECUTE IMMEDIATE 'DROP SEQUENCE ' || P_SEQUENCE;
P_NEW_COUNT := 0;
P_NEW_COUNT := MAX_ID + 1; -->当前主键最大值+1
才是SEQUENCE要更新值,才保证主键值再加入的时候不冲突; P_SQL_SEQ := 'CREATE SEQUENCE ' || P_SEQUENCE ||
' MINVALUE 1 NOMAXVALUE START WITH ' || P_NEW_COUNT ||
' INCREMENT BY 1 CACHE 20'; --创建正确的SEQUENCE语句
/*打印序列创建语句*/
/*DBMS_OUTPUT.PUT_LINE('CREATE SEQUENCE ' || P_SEQUENCE
|| ' MINVALUE 1 NOMAXVALUE START WITH '
|| P_NEW_COUNT || ' INCREMENT BY 1 CACHE
20');*/ --执行创建序列语句
EXECUTE IMMEDIATE P_SQL_SEQ;
--打印错 错误序列对应的表、序列由之前值更新到现在的值;
DBMS_OUTPUT.PUT_LINE( '错误序列对应的表:' || P_TABLE_NAME || '
' || P_SEQUENCE || ' 由' ||
P_SEQ_NUM
|| '更新到' || P_NEW_COUNT || ';' ); END IF ;
END LOOP;
END P_SYNCSEQ;
|
=> 'u1' );或者begin..传值.等)
--本文中存储打印部分注释掉了.若想看其效果将注释/**/打开.
由1000更新到1004;
转://批量更新sequence的存储的更多相关文章
- MongoDB学习笔记~大叔分享批量添加—批量更新—批量删除
回到目录 说它是批量操作,就是说将集合对象一次提交到服务器,并对数据进行持久化,如果您的代码是一次一次的提交,那不算是批量操作!在之前的mongodb仓储中并没有对批量更新和批量删除进行实现,而今天在 ...
- [转]MySQL批量更新死锁案例分析
文章出处:http://blog.csdn.net/aesop_wubo/article/details/8286215 问题描述 在做项目的过程中,由于写SQL太过随意,一不小心就抛了一个死锁异常, ...
- 如何 ︰ 执行批量更新和插入使用.NET 提供程序在 C#.NET OpenXML
https://support.microsoft.com/zh-cn/kb/315968 如何 ︰ 执行批量更新和插入使用.NET 提供程序在 C#.NET OpenXML Email Prin ...
- MySQL批量更新死锁案例分析--转载
问题描述 在做项目的过程中,由于写SQL太过随意,一不小心就抛了一个死锁异常,如下: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackE ...
- .Net中批量更新或添加数据
方法一:使用SqlBulkCopy实现批量更新或添加数据. SqlBulkCopy类一般只能用来将数据批量插入打数据库中,如果数据表中设置了主键,出现重复数据的话会报错,如果没有设置主键,那么将会添加 ...
- 【mysql】批量更新数据
概述 批量更新mysql数据表数据,上网搜索基本都会说4~5方法,本人使用的更新方式为: INSERT ... ON DUPLICATE KEY UPDATE Syntax 可参见官方网站:inser ...
- 一个简单的批量更新oracle 数据库中 最近的服务商名称的数据
有一个需求是这样的,我们需要更新数据库中的数据,数据时这样的 1.大约50万以上 2. 数据中有较多的重复数据 3. 需要将表中最近的代理商的名称赋值给行中的服务商名称 4. 代理商的名称可能有多个, ...
- SqlDataAdapter 批量更新数据库表
在数据库中批量插入数据许多人都已经了解了,就是使用.net 中的SqlBulkCopy对象(MSDN详解).我们在做评教系统的时候使用过这个对象,它能将数据表批量导入到数据库中,效率比单条插入数据效率 ...
- SQL-批量插入和批量更新
批量插入 表结构一样或类似 如果两张表的结构一样,例如一个表的结构和另一个表的结构一样,只是其中一张是临时表,而另一张表是存储数据的表,我们需要进行一次表的迁移的话,我们可以这样. insert in ...
随机推荐
- gulp报错task function must be specified
1.我npm安装了Browserify,tsify和vinyl-source-stream包,想要引用安装的插件,所以就走了引用插件的流程,修改了gulpfiles.js文件,引用流程完毕后,在终端g ...
- About me & 一些置顶的博文
About me 一只历史上最弱的 \(\text{hnoier}\) ... 身在 \(\text{hn}\) 弱校,除了在四大名校夹缝中生存,还要受到同校 \(\text{Julao}\) 的鄙视 ...
- S3C2440的中断体系结构
概述 S3C2440A中的中断控制器接受来自60个中断源的请求.提供这些中断源的可以是内部外设,如DMA控制器.UART.IIC等等.在这些中断源中,UARTn.AC97和EINTn中断对于中断控制器 ...
- 强烈推荐:240多个jQuery插件
概述 jQuery 是继 prototype 之后又一个优秀的 Javascript 框架.其宗旨是—写更少的代码,做更多的事情.它是轻量级的 js 库(压缩后只有21k) ,这是其它的 js 库所不 ...
- EL表达式和JSTL的使用
一:EL表达式 1.概述:在jsp开发中,为了获取Servlet域对象中存储的数据,经常要写很多java代码,这样的做法会使JSP页面混乱,难以维护,为此,在JSP2.0规范中提供了EL表达式.它是E ...
- Java集合之Hashtable源码分析
概述 Hashtable也是基于哈希表实现的, 与map相似, 不过Hashtable是线程安全的, Hashtable不允许 key或value为null. 成员变量 Hashtable的数据结构和 ...
- 移动端FastClick和editor冲突问题。
FastClick.prototype.needsClickForParent = function (target) { let parent = target.parent ...
- 解析<button>和<input type="button"> 的区别
一.定义和用法 <button> 标签定义的是一个按钮. 在 button 元素内部,可以放置文本或图像.这是<button>与使用 input 元素创建的按钮的不同之处. 二 ...
- blfs(systemd版本)学习笔记-前几章节的脚本配置
我的邮箱地址:zytrenren@163.com欢迎大家交流学习纠错! 记录blfs书籍前几个章节的配置内容. bash shell启动文件章节 1.切换root用户 su 2.创建/etc/prof ...
- React 入门学习笔记整理(七)—— 生命周期
(1)react 生命周期 只有类组件有生命周期,函数组件没有生命周期 1.挂载阶段:这些方法会在组件实例被创建和插入DOM中时被调用: 1)constructor(props) 初始化组件的状态.绑 ...