多个用户同时向oracle中一个表插入数据,经常出现主键冲突,主键是通过sequence获得的
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多个用户同时向oracle中一个表插入数据,经常出现主键冲突,主键是通过sequence获得的相关的知识,希望对你有一定的参考价值。
怎么防止主键冲突,使得所有数据都能正常保存进去?
这个是不可能的。Sequense是严格的序列号,除非被循环了。同时并发的要求SEQ,数据库的锁机制会将用户排队,保证获得的序列是不一样的数字。检查你的程序吧,程序的主键必然不是严格通过SEQ获得的 参考技术A 用sequence是不会出现并发问题的,除非是你人为的把序列的得到和插入数据分成两步了。 参考技术B insert into 表名(序列名字.nextval,列值1,列值2..); 参考技术C 插值时,不要插入主键啊
oracle 怎么在存储过程中创建一个临时表,在里面插入数据,再查找这个临时表的所有数据,最后drop这个表。
每次编译的时候在insert语句出都会出现找不到表的数据,如果用EXCUSE IMMEDIATE来插入能编译过去,但是执行的时候会出错,提示“列在此处不允许”。有高人给我的例子吗。
不知道楼主的需求如何一般没必要创建临时表,处理数据后又它drop。
存储过程中要用到的表应该会经常用到。就让它存在吧,用完用 truncate table 清理数据就可以了。
空表不会占很多资源。 我们就是这样做的。追问
如果不删除表的话多用户操作会不会出现问题。我这样做也就是防止这一点。
追答多用户操作确实会出问题。
可以在临时表里面加一个批次标志字段,每次运行存储过程插入数据时加上批次标志,处理后将此批次的数据删除就可以,不用truncate table,这样就不会影响到其它会话调用存储过程。
假如你的临时表的结构不是每次执行都发生变化的话
那么就是事先 通过 CREATE GLOBAL TEMPORARY TABLE 语句,把临时表建立好。
存储过程里面,就根据需要, 执行 INSERT / SELECT 之类的操作就可以了。
至于什么事情清理临时表的数据,就取决于你的临时表是 基于会话的临时表 还是 基于事务的临时表 了。
假如你的临时表的结构是每次执行都有可能发生变化的,没办法,必须动态创建的话......
这个我暂时还没学到那么透彻。
参考资料:http://hi.baidu.com/wangzhiqing999/blog/item/b390c139012393e03c6d9756.html
参考技术B create procduce testis
isql varchar2(200);
dptable varchar2(100):='drop table test';
begin
isql:='create global temporary table test (sid int,sname varchar2(20)) on commit delete rows';
execute immediate isql; --创建临时表
insert into test values (1,'abc');
execute immediate dptable; ---删除临时表
end;
-------------------
对于oracle 临时表在存储过程中调用,我是觉得这视乎没什么意义,oracle 提供在数据库里预定义临时表,只有在调用的时候才会在临时表空间里分配空间,也就是说你可以提前在数据库里创建临时表,然后再到存储过程里直接调用临时表就行了 参考技术C 我现在和你遇到一模一样的问题,应该是你动态拼sql的时候出的问题,类似下面 sqls:='INSERT INTO temp_sc_gds_product_spec
(ID, CREATE_TIME,
SPEC_ID,
SPEC_VALUE_ID,
GOODS_ID,
PRODUCT_ID
)
VALUES
(UUID(), sysdate, ' || '''' || specId ||'''' ||','|| '''' || strIndexSubstr ||'''' ||','|| '''' || goodsId || '''' || ',' ||'''' || productId || '''' || ')'; 参考技术D 见图,直接不能回复
以上是关于多个用户同时向oracle中一个表插入数据,经常出现主键冲突,主键是通过sequence获得的的主要内容,如果未能解决你的问题,请参考以下文章
Oracle中事务的处理,比如要对表A操作,我先查询在更新,是不是需要将查询放在事务,求高手解答!