当插入遇到主键重复,如何让数据库返回重复记录的那个rowid?

junnyfeng 2009-12-22 10:10:58

题目如标题,大量数据insert 进数据库,发现主键重复,我想用最快的方法获取表中重复那条记录,

不知可否用rowid,但不知怎么去获取它,或各位有什么高见请指教一下,谢谢。

...全文
357 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
junnyfeng 2009-12-26
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 shiyiwan 的回复:]
你要那个rowid做什么?

不是要返回记录吗?

还有,对大表做记录存在性检查,对性能的损失将让你得不偿失。

直接采用进攻性编程,捕获exception插入未成功的记录

引用 8 楼 junnyfeng 的回复:
引用 7 楼 crazylaa 的回复:
引用 6 楼 junnyfeng 的回复:
程序利用这个机制达到查重的目的,现在就是要从表中select这条已有记录(做其他用途)。我用proc实现的,不知道有没有方法可以更快的找到这条已有记录?

你用proc的话,直接就可以select rowid啊。


问题是怎样获取那个表里已有记录的rowid ?

[/Quote]


能否略微详细讲讲你说的这个exception怎么实现 ?

有个简单的例子就更好了。


shiyiwan 2009-12-26
  • 打赏
  • 举报
回复
我在1楼就给出代码了啊



如果不太考虑性能,不用bulk collect,就可以在insert语句外层外面加一个begin end,在里面处理exception

代码同15楼那样

[Quote=引用 14 楼 junnyfeng 的回复:]
引用 10 楼 shiyiwan 的回复:
你要那个rowid做什么?

不是要返回记录吗?

还有,对大表做记录存在性检查,对性能的损失将让你得不偿失。

直接采用进攻性编程,捕获exception插入未成功的记录

引用 8 楼 junnyfeng 的回复:
引用 7 楼 crazylaa 的回复:
引用 6 楼 junnyfeng 的回复:
程序利用这个机制达到查重的目的,现在就是要从表中select这条已有记录(做其他用途)。我用proc实现的,不知道有没有方法可以更快的找到这条已有记录?

你用proc的话,直接就可以select rowid啊。


问题是怎样获取那个表里已有记录的rowid ?




能否略微详细讲讲你说的这个exception怎么实现 ?

有个简单的例子就更好了。



[/Quote]
crazylaa 2009-12-26
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 crazylaa 的回复:]
存储过程伪码:

begin
for(。。。)loop
begin
insert into tbl values (1,'a','b');
exception when others then --插入异常,不管什么,记录日志。
insert into log_temp(tb_name,pk)values('tbl',1,othervalues);
end;
end loop;
end;
[/Quote]

仅限存储过程,如果您是jdbc的preparedStatement的executeBatch,则此法无效。因目前我还没有试出来executeBatch怎么获取批量ID。
crazylaa 2009-12-26
  • 打赏
  • 举报
回复
存储过程伪码:

begin
for(。。。)loop
begin
insert into tbl values (1,'a','b');
exception when others then --插入异常,不管什么,记录日志。
insert into log_temp(tb_name,pk)values('tbl',1,othervalues);
end;
end loop;
end;
junnyfeng 2009-12-25
  • 打赏
  • 举报
回复
程序利用这个机制达到查重的目的,现在就是要从表中select这条已有记录(做其他用途)。我用proc实现的,不知道有没有方法可以更快的找到这条已有记录?
junnyfeng 2009-12-25
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 crazylaa 的回复:]
引用 6 楼 junnyfeng 的回复:
程序利用这个机制达到查重的目的,现在就是要从表中select这条已有记录(做其他用途)。我用proc实现的,不知道有没有方法可以更快的找到这条已有记录?

你用proc的话,直接就可以select rowid啊。
[/Quote]

问题是怎样获取那个表里已有记录的rowid ?
碧水幽幽泉 2009-12-25
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 shiyiwan 的回复:]
你要那个rowid做什么?

不是要返回记录吗?

还有,对大表做记录存在性检查,对性能的损失将让你得不偿失。

直接采用进攻性编程,捕获exception插入未成功的记录

引用 8 楼 junnyfeng 的回复:
引用 7 楼 crazylaa 的回复:
引用 6 楼 junnyfeng 的回复:
程序利用这个机制达到查重的目的,现在就是要从表中select这条已有记录(做其他用途)。我用proc实现的,不知道有没有方法可以更快的找到这条已有记录?

你用proc的话,直接就可以select rowid啊。


问题是怎样获取那个表里已有记录的rowid ?

[/Quote]

学习学习
duqiangcise 2009-12-25
  • 打赏
  • 举报
回复
既然字段都已经命名为主键了,那肯定就不能够插入重复的数据了。
解决方法:
1.你在插入前先查询数据库表中是否存在待插入的主键值
2.从源头避免主键的重复,建议用oacle的sequence(或自己写个方法生成不重复的id值)。
crazylaa 2009-12-25
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 junnyfeng 的回复:]
程序利用这个机制达到查重的目的,现在就是要从表中select这条已有记录(做其他用途)。我用proc实现的,不知道有没有方法可以更快的找到这条已有记录?
[/Quote]
你用proc的话,直接就可以select rowid啊。
wh62592855 2009-12-25
  • 打赏
  • 举报
回复
select rowid from table_name where ...
shiyiwan 2009-12-25
  • 打赏
  • 举报
回复
你要那个rowid做什么?

不是要返回记录吗?

还有,对大表做记录存在性检查,对性能的损失将让你得不偿失。

直接采用进攻性编程,捕获exception插入未成功的记录

[Quote=引用 8 楼 junnyfeng 的回复:]
引用 7 楼 crazylaa 的回复:
引用 6 楼 junnyfeng 的回复:
程序利用这个机制达到查重的目的,现在就是要从表中select这条已有记录(做其他用途)。我用proc实现的,不知道有没有方法可以更快的找到这条已有记录?

你用proc的话,直接就可以select rowid啊。


问题是怎样获取那个表里已有记录的rowid ?
[/Quote]
安特矮油 2009-12-25
  • 打赏
  • 举报
回复
获取exception 然后把当条数据返回出来就OK
lovelrforever 2009-12-22
  • 打赏
  • 举报
回复
序列。
从根本上预防这个问题
可以加个错误处理,将出错的信息插入到自己建的日志表中
dawugui 2009-12-22
  • 打赏
  • 举报
回复
[Quote=引用楼主 junnyfeng 的回复:]
    题目如标题,大量数据insert 进数据库,发现主键重复,我想用最快的方法获取表中重复那条记录,

不知可否用rowid,但不知怎么去获取它,或各位有什么高见请指教一下,谢谢。


[/Quote]
如果是为了数据安全,插入前先判断一下主键是否存在.
例如:
if exists(select 1 from tb where 关键字 = 关键字的变量)
...
else
...
hjb719 2009-12-22
  • 打赏
  • 举报
回复
我通常是捕获SQL异常,将待插入的数据详细信息打印出来,这样就知道是那条数据没有插进去了。
如果是主键冲突,一眼就能看出数据库中已存在的记录是那条了。
小灰狼W 2009-12-22
  • 打赏
  • 举报
回复
rowid是不会重复的,id也没有设置主键约束吧
试试
select *
from(select a.*,count(1)over(partition by id)c from table1)
where c>1

建议id使用序列来填充,来避免重复问题
shiyiwan 2009-12-22
  • 打赏
  • 举报
回复
出错时那条数据还没有插入到数据库,获得存在于数据库中的重复记录的rowid好像没什么用吧,而且为此你还需要专门到数据库做一次查询操作。

定位到出错的记录位置就可以了吧

大批量数据处理的时候,使用forall,比如10000条。
forall i in 1 .. 10000 save exceptions
insert into t values(n(i));
exception when others then
dbms_output.put_line('Errors count:'||sql%bulk_exceptions.count);
for i in 1 .. sql%bulk_exceptions.count loop
dbms_output.put_line('index:' || sql%bulk_exceptions(i).error_index);
dbms_output.put_line('ecode:' || sql%bulk_exceptions(i).error_code);
end loop;
end;

类似于这样将错误精确定位到行

关于forall,save exceptions和集合在oracle中的使用可以google下。

17,090

社区成员

发帖
与我相关
我的任务
社区描述
Oracle开发相关技术讨论
社区管理员
  • 开发
  • Lucifer三思而后行
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧