再现理想 发表于 2015-1-16 22:42:43

MYSQL编程:在Oracle中怎样使用Rowid查找和删除表中...

业界普遍的声音认为:“MySQL是一个可靠的数据库系统,MySQL学习教程无论是在嵌入式或大型群集系统的部署中,还是在基于Web的应用程序领域。oracle|反复|反复纪录

平常事情中大概会碰到当试图对库表中的某一列或几列创立独一索引时,体系提醒ORA-01452:不克不及创立独一索引,发明反复纪录。

上面总结一下几种查找和删除反复纪录的办法(以表CZ为例):
表CZ的布局以下:
SQL>desccz
NameNull?Type
-------------------------------------------------------------------

C1NUMBER(10)
C10NUMBER(5)
C20VARCHAR2(3)

删除反复纪录的办法道理:
(1).在Oracle中,每笔记录都有一个rowid,rowid在全部数据库中是独一的,rowid断定了每笔记录是在Oracle中的哪个数据文件、块、行上。

(2).在反复的纪录中,大概一切列的内容都不异,但rowid不会不异,以是只需断定出反复纪录中那些具有最年夜rowid的就能够了,其他全体删除。

反复纪录判别的尺度是:
C1,C10和C20这三列的值都不异才算是反复纪录。

经检察表CZ统共有16笔记录:
SQL>setpagesize100
SQL>select*fromcz;

C1C10C20
-----------------------
12dsf
12dsf
12dsf
12dsf
23che
12dsf
12dsf
12dsf
12dsf
23che
23che
23che
23che
34dff
34dff
34dff
45err
53dar
61wee
72zxc

20rowsselected.

1.查找反复纪录的几种办法:
(1).SQL>select*fromczgroupbyc1,c10,c20havingcount(*)>1;
C1C10C20
-----------------------
12dsf
23che
34dff

(2).SQL>selectdistinct*fromcz;

C1C10C20
-----------------------
12dsf
23che
34dff

(3).SQL>select*fromczawhererowid=(selectmax(rowid)fromczwherec1=a.c1andc10=a.c10andc20=a.c20);
C1C10C20
-----------------------
12dsf
23che
34dff

2.删除反复纪录的几种办法:
(1).合用于有大批反复纪录的情形(在C1,C10和C20列上建有索引的时分,用以下语句效力会很高):
SQL>deleteczwhere(c1,c10,c20)in(selectc1,c10,c20fromczgroupbyc1,c10,c20havingcount(*)>1)androwidnotin
(selectmin(rowid)fromczgroupbyc1,c10,c20havingcount(*)>1);

SQL>deleteczwhererowidnotin(selectmin(rowid)fromczgroupbyc1,c10,c20);

(2).合用于有大批反复纪录的情形(注重,关于有大批反复纪录的情形,用以下语句效力会很低):
SQL>deletefromczawherea.rowid!=(selectmax(rowid)fromczbwherea.c1=b.c1anda.c10=b.c10anda.c20=b.c20);

SQL>deletefromczawherea.rowid<(selectmax(rowid)fromczbwherea.c1=b.c1anda.c10=b.c10anda.c20=b.c20);

SQL>deletefromczawhererowid<(selectmax(rowid)fromczwherec1=a.c1andc10=a.c10andc20=a.c20);

(3).合用于有大批反复纪录的情形(一时表法):
SQL>createtabletestasselectdistinct*fromcz;(建一个一时表test用来寄存反复的纪录)

SQL>truncatetablecz;(清空cz表的数据,但保存cz表的布局)

SQL>insertintoczselect*fromtest;(再将一时表test里的内容反插返来)

(4).合用于有大批反复纪录的情形(Exceptioninto子句法):
接纳altertable命令中的Exceptioninto子句也能够断定出库表中反复的纪录。这类办法略微贫苦一些,为了利用“excepeioninto”子句,必需起首创立EXCEPTIONS表。创立该表的SQL剧本文件为utlexcpt.sql。关于win2000体系和UNIX体系,Oracle寄存该文件的地位稍有分歧,在win2000体系下,该剧本文件寄存在$ORACLE_HOMEOra90dbmsadmin目次下;而关于UNIX体系,该剧本文件寄存在$ORACLE_HOME/rdbms/admin目次下。

详细步骤以下:
SQL>@?/rdbms/admin/utlexcpt.sql

Tablecreated.

SQL>descexceptions
NameNull?Type
---------------------------------------------------------------

ROW_IDROWID
OWNERVARCHAR2(30)
TABLE_NAMEVARCHAR2(30)
CONSTRAINTVARCHAR2(30)

SQL>altertableczaddconstraintcz_uniqueunique(c1,c10,c20)exceptionsintoexceptions;
*
ERRORatline1:
ORA-02299:cannotvalidate(TEST.CZ_UNIQUE)-duplicatekeysfound

SQL>createtabledupsasselect*fromczwhererowidin(selectrow_idfromexceptions);

Tablecreated.

SQL>select*fromdups;

C1C10C20
-----------------------
12dsf
12dsf
12dsf
12dsf
23che
12dsf
12dsf
12dsf
12dsf
23che
23che
23che
23che
34dff
34dff
34dff

16rowsselected.

SQL>selectrow_idfromexceptions;

ROW_ID
------------------
AAAHD/AAIAAAADSAAA
AAAHD/AAIAAAADSAAB
AAAHD/AAIAAAADSAAC
AAAHD/AAIAAAADSAAF
AAAHD/AAIAAAADSAAH
AAAHD/AAIAAAADSAAI
AAAHD/AAIAAAADSAAG
AAAHD/AAIAAAADSAAD
AAAHD/AAIAAAADSAAE
AAAHD/AAIAAAADSAAJ
AAAHD/AAIAAAADSAAK
AAAHD/AAIAAAADSAAL
AAAHD/AAIAAAADSAAM
AAAHD/AAIAAAADSAAN
AAAHD/AAIAAAADSAAO
AAAHD/AAIAAAADSAAP

16rowsselected.

SQL>deletefromczwhererowidin(selectrow_idfromexceptions);

16rowsdeleted.

SQL>insertintoczselectdistinct*fromdups;

3rowscreated.

SQL>select*fromcz;

C1C10C20
-----------------------
12dsf
23che
34dff
45err
53dar
61wee
72zxc

7rowsselected.

从了局里能够看到反复纪录已删除。
MySQL部署迅速,因此移植过程不会导致生产中断。而且,较短的学习曲线可以让你的系统管理员迅速掌握它的运行和维护。而且,MySQL的易于维护和管理意味着目前的职员可以处理目前的工作。

莫相离 发表于 2015-1-18 19:08:11

大侠们有推荐的书籍和学习方法写下吧。

再现理想 发表于 2015-1-23 05:18:49

不好!如果出了错;不好调试;不好处理!其实web开发将代码分为3层:web层;业务逻辑层和数据访问层;一般对数据库的操作都在数据访问层来做;这样便于调试和维护!而且将来如果是换了数据库的话;你只需要改数据层的代码;其他层的基本可以不变!要是你在jsp中直接调用sql数据库;那么如果换了数据库呢?岂不都要改?如果报了异常呢?怎么做异常处理?

谁可相欹 发表于 2015-1-31 13:33:47

对一张百万级别的表建游标,同时又没有什么过滤条件,取得游标效率是如果直接SQL查询百万条数据;如果再对每条记录做处理,耗时将更长。

再见西城 发表于 2015-2-6 19:34:24

你觉得我的非分区索引无法对起子分区,你可以提醒我一下呀!没有任何的提醒,直接就变成了非分区表。不知道这算不算一个bug。大家也可以试试。

海妖 发表于 2015-2-18 10:54:13

代替了原来VB式的错误判断。比Oracle高级不少。

小女巫 发表于 2015-3-6 04:22:59

多走走一此相关论坛,多看一些实例开发,多交流0经验,没什么的,我也是刚学没多久!加油

变相怪杰 发表于 2015-3-12 20:37:04

我个人认为就是孜孜不懈的学习

乐观 发表于 2015-3-20 02:22:35

需要注意的一点,也是我使用过程中发现的一个问题。在建立function->schema->table后,如果在现有的分区表上建立没有显式声明的聚集索引时,分区表会自动变为非分区表。这一点很让我纳闷。
页: [1]
查看完整版本: MYSQL编程:在Oracle中怎样使用Rowid查找和删除表中...