oracle数据库,主键设置为ID,插入语句时,如何自动生成ID并让它顺序增加呢

oracle数据库,主键设置为ID,插入语句时,如何自动生成ID并让它顺序增加呢,第1张

使用oracle数据库中的关键字sequence来实现目的。

//创建mySeq

create sequence mySeq

start with 1

increment by 2

maxvalue 40

minvalue 1

cycle

//创建用户表

create table USER

(

Id int,

CompName varchar2(20)

)

插入语句可以这样写:

insert into USER values(mySeqnextVal,'AA')

这样的话每次插入的ID就是自动递增的

扩展资料:

sequence用法:

create sequence <序列名称>

start with <起始数>

increment by <增长量>

[maxvalue 值]

[minvalue 值]

[cycle 当到达最大值的时候,将继续从头开始]

[Nocycle -- 一直累加,不循环]

[Cache ]

参考资料:百度百科-oraclesequence

主键是用来唯一标识每一行数据的,而text类型只能存储文本数据。数据库表不能只设置一个主键和一个text类型,因为主键是用来唯一标识每一行数据的,而text类型只能存储文本数据,不能用来唯一标识每一行数据,所以不能只设置一个主键和一个text类型。此外,如果只设置一个text类型,那么数据库表中的数据将无法进行序列化,从而无法实现数据的查询和更新等 *** 作。

1 Oracle是大型数据库而Mysql是中小型数据库,Oracle市场占有率达40%,Mysql只有20%左右,同时Mysql是开源的而Oracle价格非常高。\x0d\2 Oracle支持大并发,大访问量,是OLTP最好的工具。\x0d\3 安装所用的空间差别也是很大的,Mysql安装完后才152M而Oracle有3G左右,且使用的时候Oracle占用特别大的内存空间和其他机器性能。\x0d\4Oracle也Mysql *** 作上的一些区别\x0d\①主键\x0d\Mysql一般使用自动增长类型,在创建表时只要指定表的主键为auto increment,插入记录时,不需要再指定该记录的主键值,Mysql将自动增长;Oracle没有自动增长类型,主键一般使用的序列,插入记录时将序列号的下一个值付给该字段即可;只是ORM框架是只要是native主键生成策略即可。\x0d\②单引号的处理\x0d\MYSQL里可以用双引号包起字符串,ORACLE里只可以用单引号包起字符串。在插入和修改字符串前必须做单引号的替换:把所有出现的一个单引号替换成两个单引号。\x0d\③翻页的SQL语句的处理\x0d\MYSQL处理翻页的SQL语句比较简单,用LIMIT 开始位置, 记录个数;ORACLE处理翻页的SQL语句就比较繁琐了。每个结果集只有一个ROWNUM字段标明它的位置, 并且只能用ROWNUM80\x0d\④ 长字符串的处理\x0d\长字符串的处理ORACLE也有它特殊的地方。INSERT和UPDATE时最大可 *** 作的字符串长度小于等于4000个单字节, 如果要插入更长的字符串, 请考虑字段用CLOB类型,方法借用ORACLE里自带的DBMS_LOB程序包。插入修改记录前一定要做进行非空和长度判断,不能为空的字段值和超出长度字段值都应该提出警告,返回上次 *** 作。\x0d\⑤空字符的处理\x0d\MYSQL的非空字段也有空的内容,ORACLE里定义了非空字段就不容许有空的内容。按MYSQL的NOT NULL来定义ORACLE表结构, 导数据的时候会产生错误。因此导数据时要对空字符进行判断,如果为NULL或空字符,需要把它改成一个空格的字符串。\x0d\⑥字符串的模糊比较\x0d\MYSQL里用 字段名 like '%字符串%',ORACLE里也可以用 字段名 like '%字符串%' 但这种方法不能使用索引, 速度不快。\x0d\⑦Oracle实现了ANSII SQL中大部分功能,如,事务的隔离级别、传播特性等而Mysql在这方面还是比较的弱

假设我们有一个java实体类User,它有三个属性:

 private Integer id; //主键

 private String name; //姓名

 private double rate; //进度

构造方法、setter、getter都是正常且完善的。

数据库中有一张对应的t_user表:

 --mysql数据库

 create table t_user

 (

  id integer primary key auto_increment,

  name varchar(20),

  rate double

 )engine=INNODB;

或者

 --oracle数据库

 create table t_user

 (

  id number(11) primary key,

  name varchar2(20),

  rate number(10,2)

 );

 

 --主键序列

 create sequence seq_user_id;

在Userxml配置文件中,插入User的配置一般为:

<insert id="insertUser" parameterClass="User">

insert into t_user (ID, NAME, RATE) values (#id#, #name#, #rate#)

</insert>

这样,在java代码中调用方式为:

 sqlMapperinsert("insertUser", user); //此处的user应该保证id是正确的

为了使用ibatis生成主键,我们可以使用如下配置:

 <!-- mysql -->

 <insert id="insertUserByAutoIncrement" parameterClass="User">

  insert into t_user (NAME,RATE) values (#name#, #rate#)

  <!-- 注意:上述SQL语句中不插入主键id -->

  <selectKey resultClass="int" keyProperty="id">

   SELECT LAST_INSERT_ID() AS VALUE

  </selectKey>

 </insert>

或者

 <!-- Oracle -->

 <insert id="insertUserBySequence" parameterClass="User">

  <selectKey resultClass="int" keyProperty="id">

   SELECT seq_user_idNEXTVAL AS VALUE FROM DUAL

  </selectKey>

  <!-- 注意:下列SQL语句中必须插入ID -->

  insert into t_user (ID, NAME, RATE) values (#id#, #name#, #rate#)

 </insert>

注意,这里需要说明一下,不同的数据库,主键生成方式是不同的

mysql:SELECT LAST_INSERT_ID() AS VALUE

mssql:select @@IDENTITY as value

oracle:SELECT SEQUENCENEXTVAL [AS VALUE] FROM DUAL

还有一点需要注意的是有些数据库是预先生成 (pre-generate)主键的,如Oracle和PostgreSQL,有些数据库是事后生成(post-generate)主键的,如MySQL和SQL Server。所以如果是Oracle数据库,则需要将selectKey写在insert之前。

序列是一数据库对象,利用它可生成唯一的整数。一般使用序列自动地生成主码值。一个序列的值是由特殊的Oracle程序自动生成,因此序列避免了在应用层实现序列而引起的性能瓶颈。Oracle序列允许同时生成多个序列号,而每一个序列号是唯一的。当一个序列号生成时,序列是递增,独立于事务的提交或回滚。允许设计缺省序列,不需指定任何子句。该序列为上升序列,由1开始,增量为1,没有上限。 1) 建立序列命令 网管网 >

关于数据库的逻辑设计 是一个很广泛的问题 本文主要针对开发应用中遇到在MS SQL Server上进行表设计时 对表的主键设计应注意的问题以及相应的解决办法

主键设计现状和问题

关于数据库表的主键设计 一般而言 是根据业务需求情况 以业务逻辑为基础 形成主键

比如 销售时要记录销售情况 一般需要两个表 一个是销售单的概要描述 记录诸如销售单号 总金额一类的情况 另外一个表记录每种商品的数量和金额 对于第一个表(主表) 通常我们以单据号为主键;对于商品销售的明细表(从表) 我们就需要将主表的单据号也放入到商品的明细表中 使其关联起来形成主从关系 同时该单据号与商品的编码一起 形成明细表的联合主键 这只是一般情况 我们稍微将这个问题延伸一下 假如在明细中 我们每种商品又可能以不同的价格方式销售 有部分按折扣价格销售 有部分按正常价格销售 要记录这些情况 那么我们就需要第三个表 而这第三个表的主键就需要第一个表的单据号以及第二个表的商品号再加上自身需要的信息一起构成联合主键;又或者其他情况 在第一个主表中 本身就是以联合方式构成联合主键 那么也需要在从表中将主表的多个字段添加进来联合在一起形成自己的主键

数据冗余存储 随着这种主从关系的延伸 数据库中需要重复存储的数据将变得越来越庞大 或者当主表本身就是联合主键时 就必须在从表中将所有的字段重新存储一次

SQL复杂度增加 当存在多个字段的联合主键时 我们需要将主表的多个字段与子表的多个字段关联以获取满足某些条件的所有详细情况记录

程序复杂度增加 可能需要传递多个参数

效率降低 数据库系统需要判断更多的条件 SQL语句长度增加 同时 联合主键自动生成联合索引

WEB分页困难 由于是联合主键方式(对于多数的子表) 那么在WEB页面上要进行分页处理时 在自关联时 难于处理

解决方案

从上面 我们已经看到现有结构存在着相当多的弊端 主要是导致程序复杂 效率降低并且不利于分页

为解决上述问题 本文提出 当应用系统后台数据库表间存在主从关系时 数据库表额外增加一非业务字段作为主键 该字段为数值型;或者当该表需要在应用中进行分页查询时 也应考虑如此设计 一般地 我们也可以几乎为任何表增加一个与业务逻辑无关的字段作为该表的主键字段

由于该字段要作为表的主键 那么其首要条件是要保证在该表中要具有唯一性 同时 结合SQL Server数据库自身的特性 可以为其建立一个自增列

create TABLE T_PK_DEMO ( U_ID  BIGINT NOT NULL IDENTITY( ) –唯一标识记录的ID COL_OTHER VARchar( ) NOT NULL  –其他列 CONSTRAINT PK_T_PK_DEMO PRIMARY KEY NONCLUSTERED (U_ID)–定义为主键 )

但是 SQL Server中的自增列却存在一个比较尴尬的事实 那就是该字段一旦定义和使用 用户无法直接干预该字段的值 完全由数据库系统自身控制

完全数据库系统控制 用户无法修改值

在数据库的发布和订阅时 使用自增列会比较麻烦

恢复部分数据时 使用自增列会比较麻烦

该列的值必须在插入数据后才能获取

鉴于此 建议不以自增列的方式来定义 而是参考Oracle数据库系统中序列 在SQL Server系统中实现类似Oracle数据库系统序列功能 这个具体在下面的小节中介绍 我们只需要按照普通字段的定义方式修改表定义为

create TABLE T_PK_DEMO ( U_ID  BIGINT NOT NULL –唯一标识记录的ID COL_OTHER VARchar( ) NOT NULL –其他列 CONSTRAINT PK_T_PK_DEMO PRIMARY KEY NONCLUSTERED (U_ID)–定义为主键 )

参照Oracle序列的功能 我们需要在SQL Server数据库中创建一个新表 以管理序列值

create TABLE T_DB_SEQ ( SEQ_NAMEVARchar( ) NOT NULL  –序列名称 SEQ_OWNER  VARchar( ) NOT NULL DEFAULT ’DBO’ –序列所有者(SYSTEM_USER) SEQ_CURRENT BIGINT NOT NULL DEFAULT –序列当前值 SEQ_MIN BIGINT NOT NULL DEFAULT –序列最小值 SEQ_MAX BIGINT NOT NULL DEFAULT –序列最小值 SEQ_MAX BIGINT NOT NULL DEFAULT –序列最大值 SEQ_STEPINT NOT NULL DEFAULT –序列增长步长 IF_CYCLEINT NOT NULL DEFAULT –是否循环( 不循环; 循环) CONSTRAINT T_DB_SEQ PRIMARY KEY CLUSTERED (SEQ_NAME SEQ_OWNER)–主键 )

应用系统为需要创建自增列的表创建一个序列名称 在表“T_DB_SEQ”中反映为数据库中的一行

第一 需要为需要建立序列的表创建一个序列 采用方法 F_create_SEQ(序列名) 该函数传入序列的名称 在表“T_DB_SEQ”插入一行 序列的所有者 采用系统变量SYSTEM_USER

第二 获取下一个值 采用方法 F_GET_NEXT_SEQ_VAL(序列名) 该函数根据序列名获取该序列的下一个值 根据当前值与增长步长得到 同时 该函数保证在同时获取同一个序列时 应保证并发一致性

第三 将返回值返回到应用使用

此外 为保证应用的完整性 可能还需要提供一些方法的重载方法 同时提供一些其他方法

获取序列当前值 F_GET_SEQ_CUR_VAL(序列名)

设置序列值 F_SET_SEQ_VAL(序列名)

删除序列 F_DEL_SEQ(序列名)

判断序列是否存在 F_SEQ_exists(序列名)

在主从关系的表设计中 子表也使用序列字段作为唯一主键 将父表的序列字段作为外键关联

create TABLE T_PK_DEMO_C ( U_ID  BIGINT NOT NULL –唯一标识记录的ID COL_OTHER VARchar( ) NOT NULL –其他列 P_ID  INT NOT NULL –父表ID CONSTRAINT PK_T_PK_DEMO_C PRIMARY KEY NONCLUSTERED (U_ID)–定义为主键 CONSTRAINT FK_T_PK_DEMO_C FOREIGN KEY (P_ID) REFERENCES T_PK_DEMO(U_ID) ON delete CASCADE )

使用序列的问题及解决办法

由于系统使用一个额外增加一个字段作为主键 因此没有为业务逻辑建立主键约束 比如在企业用户信息表中 要求企业中用户登录名必须唯一 一般在创建表时 以登录名作为主键 这个时候在数据库层自然的创建另一个主键唯一性约束 而现在没有使用登录名作为主键 那么就没有这个约束 解决办法

一是在数据库层解决 可以为该表创建一个唯一(UNIQUE)约束或者唯一索引 如

alter TABLE T_PK_DEMO ADD CONSTRAINT C_T_PK_DEMO UNIQUE NONCLUSTERED(COL_OTHER) 唯一约束

create UNIQUE INDEX IX_T_PK_DEMO ON T_PK_DEMO(COL_OTHER) – 唯一索引

二是在应用端解决 也就是在应用中判断该列是否有重复值 然后根据判断结果来保证唯一性

我们注意到 在之前的例子中 主键采用了NONCLUSTERED(非聚蔟)的索引方式 关于如何设计索引 不是本文的重点 在这里仅提供一个建立索引时采用聚蔟方式还是非聚蔟方式的一个一般原则

作为非业务字段的主键列 是一个没有重复值的 基本不进行更新 *** 作的列 并且 在SQL Server数据库中 聚蔟索引在一个表中只能有一个 因此 聚蔟索引非常重要 需要留给更重要的字段来使用 因此 对照上表和根据聚蔟索引的重要程度 在此处采用非聚蔟方式创建其索引

具体应用

采用这种主键设计方式 有诸多好处 这已经在前文说明 现在就以一个具体的应用来说明如何使用这个主键

lishixinzhi/Article/program/SQLServer/201311/22342

以上就是关于oracle数据库,主键设置为ID,插入语句时,如何自动生成ID并让它顺序增加呢全部的内容,包括:oracle数据库,主键设置为ID,插入语句时,如何自动生成ID并让它顺序增加呢、数据库表为什么不可以只设置一个主键,一个text类型,序列化、“Oracle”和“MYSQL”各自的特点是什么等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/sjk/9879438.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-02
下一篇2023-05-02

发表评论

登录后才能评论

评论列表(0条)

    保存