wsnow
路人甲
路人甲
  • 注册日期2007-06-12
  • 发帖数6
  • QQ
  • 铜币135枚
  • 威望0点
  • 贡献值0点
  • 银元0个
阅读:2662回复:2

orcal中自动编号的问题

楼主#
更多 发布于:2007-09-12 16:39
<P>求助!</P>
<P>做了一个程序,开始用access建的表,其中有一个ID字段是字段编号类型的 </P>
<P>现在表转到orcal数据库中,程序瘫痪了 </P>
<P>我没有找到orcal中的自动编号 </P>
<P>请问该怎么实现 !!</P>
<P>急 </P>
<P>在线等!!</P>
<P>谢谢 </P>
喜欢0 评分0
gis
gis
管理员
管理员
  • 注册日期2003-07-16
  • 发帖数15945
  • QQ554730525
  • 铜币25337枚
  • 威望15352点
  • 贡献值0点
  • 银元0个
  • GIS帝国居民
  • 帝国沙发管家
  • GIS帝国明星
  • GIS帝国铁杆
1楼#
发布于:2007-09-13 00:46
<P>在access中有自动编号的数据类型,MSSQL和MYSQL也都有自动增长的数据类型,插入记录时不用操作此字段,会自动获得数据值,而oracle没有自动增长的数据类型,我们需要建立一个自动增长的序列号,插入记录时要把序列号的下一个值赋于此字段,可以预见的是,有此功能,我们可以把数据从ACCESS、MSSQL或MYSQL迁移到oracle了!<BR>create sequence type_id increment by 1 start with 1;<BR>这句中,type_id为序列号的名称,每次增长为1,起始序号为1。<BR>如果要删除序列,用drop sequence 序列名就可以了!!<BR><BR>序列可以保证多个用户对同一张表进行操作时生成唯一的整数,利用序列可以自动生成主关键字,序列只存在于数据字典中.<BR><BR>CREATE SEQUENCE sequence<BR>[INCREMENT BY n]<BR>[START WITH n]<BR>[{MAXVALUE n|NOMAXVALUE}]<BR>[{MINVALUE n|NOMINVALUE}]<BR>[{CYCLE |NOCYCLE}]<BR>[{CACHE n|NOCACHE}];<BR>INCREMENT BY--指定步长<BR>START WITH--指定初始值<BR>MAXVALUE--定义序列生成的最大编号.默认的MAXVALUE就是NOMAXVALUE,对于递增序列为10^27,对于递减序列为-1<BR>MINVALUE--定义序列的最小编号,默认的MINVALUE为NOMINVALUE,对于递增序列为1,递减序列为-10^26.<BR>CYCLE--配置序列在达到界限值时重复编号<BR>NOCYCLE--达到界限值时不重复编号,这是默认值,当你试图生成MAXVALUE+1时将返回异常.<BR>CACHE--定义在内存中保留的序列编号块的大小,默认值为20.<BR>NOCACHE--强制数据词典对于生成的每个序列编号进行更新,保证在生成的编号中没有空缺,但这样会降低性能.<BR><BR>生成一个序列<BR>CREATE SEQUENCE dept_deptid_seq<BR>INCREAMENT BY 10<BR>START WITH 120<BR>MAXVALUE 9999<BR>NOCACHE<BR>NOCYCLE;<BR>//如果是用来生成主键值的话,不要用CYCLE选项,而且命名序列时最好能体现它的潜在用途以便于理解.<BR><BR>确认序列<BR>SELECT sequence_name,min_value,max_value,increament_by,last_number<BR>FROM user_sequences;<BR>//如果你指定了NOCACHE选项,那么LAST_NUMBER列将显示下一可用的序列号.<BR><BR>使用NEXTVAL可以访问序列中的下一个编号,但问题常常出现在会话初始序列之前查询其当前序列号CURRVAL<BR>CREATE SEQUENCE emp_seq<BR>NOMAXVALUE<BR>NOCYCLE;<BR>然后查询<BR>SELECT emp_seq.currval<BR>FROM dual;<BR>将返回错误,问题就在于你视图引用CURRVAL之前,在你的会话中并没有使用NEXTVAL先初始化此序列.<BR>SELECT emp_seq.nextval<BR>FROM dual;<BR>这样再查询CURRVAL就不会出错了.<BR><BR>使用序列<BR>INSERT INTO departments(department_id,department_name,location_id)<BR>VALUES (dept_deptid_seq.NEXTVAL,'Support',2500);<BR><BR>对序列进行缓冲存储可以提高性能,因为这样就不必对每个生成的编号都更新数据字典表,只需要对每一组编号进行更新即可.这样,在我们查询NEXTVAL时就直接从缓冲中提取,速度将快很多,但是进行序列缓冲带来的负面影响就是当数据库被回滚时,比如说系统崩溃,手动ROLLBACK数据时,在缓冲中存储的序列值将会丢失,这也就是为什么会出现空缺(GAPS),如果生成序列时指定的是NOCACHE,那么可以在USER_SEQUENCES表里查询下一个可用的序列号值,这个查询并不会产生增加序列值的动作.<BR><BR>修改序列<BR>ALTER SEQUENCE dept_deptid_seq<BR>INCREMENT BY 20<BR>MAXVALUE 999999<BR>NOCACHE<BR>NOCYCLE;<BR>规则:<BR>>必须为序列的所有者或者拥有ALTER特权<BR>>修改对于以后的序列号生效<BR>>序列必须是被删除然后重新生成(使所有相关的对象失效,并且失去相应的关联)<BR>>修改时还要满足些其他的验证条件,比如说新的MAXVALUE不可以比现在的序列号低<BR><BR>删除序列<BR>DROP SEQUENCE dept_deptid_seq;<BR>>必须要时序列的所有者或者有DROP ANY SEQUENCE的权限<BR><BR>索引<BR>索引是通过获取特定的行信息而与默认的全表扫描相比大大提高系统性能的数据结构.可是显式的手动建立,也可一由ORACLE自动生成,它们是与之索引的表相独立的,就是说,可以在任何时候建立或者删除索引而对基表或者其他索引无任何影响(当你删除表时,相关的索引将会被删除).<BR>有两种索引<BR>>唯一索引--当你定义了一列含有主键或者唯一键约束时将自动生成一个唯一索引(可以手动建立,但是推荐由ORACLE自动建立)<BR>>非唯一索引--当你手动为一个查询中的连接建立一个外键索引来加速查询速度时<BR><BR>建立索引<BR>CREATE INDEX index<BR>ON table (column[,column]...);<BR>e.g.<BR>CREATE INDEX emp_last_name_idx<BR>ON employees(last_name);<BR><BR>何时使用索引<BR>>当一个列包含的数值范围较大时<BR>>当一列包含大量空值时<BR>>一个或者多个列经常一起在WHERE子句或者JOIN子句中使用时<BR>>表非常大,但是大多数的查询只要求检索少于2-4个百分点的行记录<BR><BR>何时不该使用索引<BR>>表很小时<BR>>列并不经常作为查询中的条件使用时<BR>>大多数查询都检索多于4个百分点的行记录<BR>>表经常被更新<BR>>索引列被作为表达式的一部分引用<BR><BR>索引虽然可以很大程度提高检索性能,但是越多的索引,意味着在DML操作之后ORACLE就将花越多的功夫去更新索引.所以,一定要适时使用,<BR><BR>确认索引<BR>查询数据字典视图USER_INDEXES和USER_IND_COLUMNS可以检索到索引的相关信息<BR>SELECT ic.index_name,ic.column_name,<BR>ic.column_position col_pos,ix.uniqueness<BR>FROM user_indexes ix,user_ind_columns ic<BR>WHERE ic.inde_name=ix.index_name<BR>AND ic.table_name='EMPLOYEES';<BR><BR>基于函数的索引<BR>CREATE INDEX upper_dept_name_idx<BR>ON departments(UPPER(department_name));<BR>//但是如果想保证ORACLE使用索引而不是全表扫描就必须保证函数值非空,就是需要加个WHERE子句指定非空如<BR>SELECT *<BR>FROM employees<BR>WHERE UPPER(last_name_ IS NOT NULL<BR>ORDER BY UPPER(last_name);<BR>如果没有WHERE子句,则将会进行全表扫描非使用索引了.<BR><BR>删除索引<BR>DROP INDEX index;<BR>//当你删除一个表时,索引和约束将会自动删除,但是视图和序列将会保留.<BR><BR>同义词<BR>同义词经常用来通过为一个本地或者远程对象给定一个通用的名字来简化SQL.同义词可以指向一个表,视图,序列,过程,函数或者本地数据库中的包,或者通过一个数据库连接指向另一个数据库中的对象.公共同义词可供所有用户使用,而专用同义词则只能供其所有者或者获得了相关授权的帐户所有者使用.<BR>比如说SCOTT拥有表EMP,所有用户都使用自己的用户名登陆数据库,并且必须引用该表,即SCOTT.EMP,如果我们为其生成一个同义词EMP,每个对该表具有相关特权的人都可以简单地在自己的SQL或者PL/SQL语句中以EMP的形式来引用它,不需要再指出所有者了.<BR><BR>CREATE [PUBLIC] SYNONYM synonym<BR>FOR object;<BR><BR>e.g.<BR>CREATE SYNONYM d_sum<BR>FOR dept_sum_vu;<BR><BR>DROP SYNONYM d_sum;<BR><BR>CREATE PUBLIC SYNONYM dept<BR>FOR alice.departments;<BR><BR>DROP PUBLIC SYNONYM dept;<BR>//仅仅数据库管理员可以删除公共同义词<BR></P>
<P>
<HR color=#ff0000 SIZE=1>


<DIV>关于Oracle的序列(Sequence)使用</DIV>
<DIV>序列是一数据库对象,利用它可生成唯一的整数。一般使用序列自动地生成主键值。对我们程序员来讲,精力时间有限,我们只学最有用的知识。大家请看:</DIV>
<H2>1) 建立序列命令</H2>
<DIV>CREATE SEQUENCE [user.]sequence_name<BR>[increment by n]<BR>[start with n]<BR>[maxvalue n | nomaxvalue]<BR>[minvalue n | nominvalue];<BR>[NOCYCLE]  -- <BR>INCREMENT BY: 指定序列号之间的间隔,该值可为正的或负的整数,但不可为0。序列为升序。忽略该子句时,缺省值为1。<BR>START WITH:指定生成的第一个序列号。在升序时,序列可从比最小值大的值开始,缺省值为序列的最小值。对于降序,序列可由比最大值小的值开始,缺省值为序列的最大值。<BR>MAXVALUE:指定序列可生成的最大值。<BR>NOMAXVALUE:为升序指定最大值为1027,为降序指定最大值为-1。<BR>MINVALUE:指定序列的最小值。<BR>NOMINVALUE:为升序指定最小值为1。为降序指定最小值为-1026。<BR>NOCYCLE:一直累加,不循环</DIV>
<H2>2) 更改序列命令</H2>
<DIV>ALTERSEQUENCE [user.]sequence_name<BR>[INCREMENT BY n]<BR>[MAXVALUE n| NOMAXVALUE ]<BR>[MINVALUE n | NOMINVALUE];<BR>修改序列可以:<BR>    修改未来序列值的增量。<BR>    设置或撤消最小值或最大值。<BR>    改变缓冲序列的数目。<BR>    指定序列号是否是有序。</DIV>
<P>注意:<BR>1,第一次NEXTVAL返回的是初始值<BR>2,可以alter除start至以外的所有sequence参数.如果想要改变start值,必须 drop sequence 再 re-create .<BR><BR>
<DIV></DIV>
<H2>3) 删除序列命令</H2>
<DIV>DROP SEQUENCE [user.]sequence_name;<BR>用于从数据库中删除一序列。</DIV>
<H2>4)牛刀小试</H2>
<DIV>     4.1)创建一个序列号的语句:</DIV>
<DIV>-- Create sequence <BR>create sequence NCME_QUESTION_SEQ<BR>minvalue 1<BR>maxvalue 999999999999<BR>start with 1<BR>increment by 1<BR>nocache;<BR><BR>/////////////////////////////////////////////////////////////////////////////////////////</DIV>
<DIV>4.2)SQL中取序列号的用法:</DIV>
<DIV>SELECT NCME_QUESTION_SEQ.nextval FROM dual<BR>SELECT NCME_QUESTION_SEQ.CURRVAL FROM dual</DIV>
<DIV> </DIV>
<DIV>注意:在使用序列的时候,有时需要有用户名,就像这样:</DIV>
<DIV>insert into system.CONSERVATOR(CONSERVATORNAME,CONPASS,CONTRUENAME,CONSEX,CONID)values('JG','123456','000',0, system.CONID.nextval);</DIV>
举报 回复(0) 喜欢(0)     评分
fatway
路人甲
路人甲
  • 注册日期2004-09-28
  • 发帖数23
  • QQ
  • 铜币184枚
  • 威望0点
  • 贡献值0点
  • 银元0个
2楼#
发布于:2007-11-12 14:35
<P>老大正解</P>
<P>用序列</P>
举报 回复(0) 喜欢(0)     评分
游客

返回顶部