oracle int auto_increment,sql - 如何在Oracle上使用AUTO_INCREMENT创建id?

sql - 如何在Oracle上使用AUTO_INCREMENT创建id?

似乎在Oracle中没有AUTO_INCREMENT的概念,直到包括版本11g。

如何在Oracle 11g中创建一个行为类似自动增量的列?

16个解决方案

482 votes

从Oracle 11g开始,Oracle中没有“auto_increment”或“identity”列。 但是,您可以使用序列和触发器轻松地对其进行建模:

表定义:

CREATE TABLE departments (

ID NUMBER(10) NOT NULL,

DESCRIPTION VARCHAR2(50) NOT NULL);

ALTER TABLE departments ADD (

CONSTRAINT dept_pk PRIMARY KEY (ID));

CREATE SEQUENCE dept_seq START WITH 1;

触发定义:

CREATE OR REPLACE TRIGGER dept_bir

BEFORE INSERT ON departments

FOR EACH ROW

BEGIN

SELECT dept_seq.NEXTVAL

INTO :new.id

FROM dual;

END;

/

更新:

2164038927536489472列现在可用于Oracle 12c:

create table t1 (

c1 NUMBER GENERATED by default on null as IDENTITY,

c2 VARCHAR2(10)

);

或指定起始值和增量值,同时防止任何插入标识列(GENERATED ALWAYS)(同样,仅限Oracle 12c +)

create table t1 (

c1 NUMBER GENERATED ALWAYS as IDENTITY(START with 1 INCREMENT by 1),

c2 VARCHAR2(10)

);

或者,Oracle 12还允许使用序列作为默认值:

CREATE SEQUENCE dept_seq START WITH 1;

CREATE TABLE departments (

ID NUMBER(10) DEFAULT dept_seq.nextval NOT NULL,

DESCRIPTION VARCHAR2(50) NOT NULL);

ALTER TABLE departments ADD (

CONSTRAINT dept_pk PRIMARY KEY (ID));

Eugenio Cuevas answered 2019-01-10T23:28:50Z

79 votes

SYS_GUID返回GUID--全局唯一ID。 SYS_GUID是RAW(16).它不生成递增的数值。

如果要创建递增数字键,则需要创建序列。

CREATE SEQUENCE name_of_sequence

START WITH 1

INCREMENT BY 1

CACHE 100;

然后,您可以在SYS_GUID语句中使用该序列

INSERT INTO name_of_table( primary_key_column, <> )

VALUES( name_of_sequence.nextval, <> );

或者,您可以定义一个触发器,使用序列自动填充主键值

CREATE OR REPLACE TRIGGER trigger_name

BEFORE INSERT ON table_name

FOR EACH ROW

BEGIN

SELECT name_of_sequence.nextval

INTO :new.primary_key_column

FROM dual;

END;

如果您使用的是Oracle 11.1或更高版本,则可以稍微简化触发器

CREATE OR REPLACE TRIGGER trigger_name

BEFORE INSERT ON table_name

FOR EACH ROW

BEGIN

:new.primary_key_column := name_of_sequence.nextval;

END;

如果你真的想用SYS_GUID

CREATE TABLE table_name (

primary_key_column raw(16) default sys_guid() primary key,

<>

)

Justin Cave answered 2019-01-10T23:29:43Z

40 votes

在Oracle 12c中你可以做类似的事情,

CREATE TABLE MAPS

(

MAP_ID INTEGER GENERATED ALWAYS AS IDENTITY (START WITH 1 INCREMENT BY 1) NOT NULL,

MAP_NAME VARCHAR(24) NOT NULL,

UNIQUE (MAP_ID, MAP_NAME)

);

在Oracle(Pre 12c)中。

-- create table

CREATE TABLE MAPS

(

MAP_ID INTEGER NOT NULL ,

MAP_NAME VARCHAR(24) NOT NULL,

UNIQUE (MAP_ID, MAP_NAME)

);

-- create sequence

CREATE SEQUENCE MAPS_SEQ;

-- create tigger using the sequence

CREATE OR REPLACE TRIGGER MAPS_TRG

BEFORE INSERT ON MAPS

FOR EACH ROW

WHEN (new.MAP_ID IS NULL)

BEGIN

SELECT MAPS_SEQ.NEXTVAL

INTO :new.MAP_ID

FROM dual;

END;

/

Nisar answered 2019-01-10T23:30:11Z

31 votes

这有三种口味:

数字。 简单地增加数值,例如1,2,3,...

GUID。 全局univeral标识符,作为x数据类型。

GUID(字符串)。 与上面相同,但作为一个字符串,在某些语言中可能更容易处理。

x是标识列。 在每个示例中用您的表名替换FOO。

-- numerical identity, e.g. 1,2,3...

create table FOO (

x number primary key

);

create sequence FOO_seq;

create or replace trigger FOO_trg

before insert on FOO

for each row

begin

select FOO_seq.nextval into :new.x from dual;

end;

/

-- GUID identity, e.g. 7CFF0C304187716EE040488AA1F9749A

-- use the commented out lines if you prefer RAW over VARCHAR2.

create table FOO (

x varchar(32) primary key -- string version

-- x raw(32) primary key -- raw version

);

create or replace trigger FOO_trg

before insert on FOO

for each row

begin

select cast(sys_guid() as varchar2(32)) into :new.x from dual; -- string version

-- select sys_guid() into :new.x from dual; -- raw version

end;

/

更新:

Oracle 12c引入了这两种不依赖于触发器的变体:

create table mytable(id number default mysequence.nextval);

create table mytable(id number generated as identity);

第一个使用传统方式的序列; 第二个在内部管理价值。

Mark Harrison answered 2019-01-10T23:31:17Z

7 votes

假设您的意思是像SQL Server标识列一样的列?

在Oracle中,您使用SEQUENCE来实现相同的功能。 我会看看我是否能找到一个好的链接并在此发布。

更新:看起来你自己找到了它。 无论如何这是链接:[http://www.techonthenet.com/oracle/sequences.php]

Phil Sandler answered 2019-01-10T23:31:51Z

7 votes

Oracle Database 12c引入了Identity,这是一个自动增量(系统生成)列。在以前的数据库版本中(直到11g),您通常通过创建序列和触发器来实现Identity。从12c开始,您可以创建自己的表并定义必须作为标识生成的列。

以下文章解释了如何使用它:

标识列 - Oracle Database 12c中的新条目

Corrado Piola answered 2019-01-10T23:32:27Z

5 votes

当您想要任何人都可以轻松阅读/记忆/理解的序列号时,可以使用emp_id和Sequence。 但是如果你不想通过这种方式管理ID列(比如emp_id),并且这个列的值不是很大,你可以在Table Creation中使用SYS_GUID()来获得这样的自动增量。

CREATE TABLE

(emp_id RAW(16) DEFAULT SYS_GUID() PRIMARY KEY,

name VARCHAR2(30));

现在,您的emp_id列将接受“全局唯一标识符值”。你可以通过忽略这样的emp_id列在表中插入值。

INSERT INTO (name) VALUES ('name value');

因此,它将为您的emp_id列插入唯一值。

N J answered 2019-01-10T23:33:02Z

5 votes

从Oracle 12c开始,可以通过以下两种方式之一支持Identity列:

序列+表 - 在此解决方案中,您仍然可以像往常一样创建序列,然后使用以下DDL:

CREATE TABLE MyTable(ID号码默认MyTable_Seq.NEXTVAL,...)

仅表 - 在此解决方案中,未明确指定序列。 您将使用以下DDL:

CREATE TABLE MyTable(生成的ID号为身份,......)

如果您使用第一种方式,它向后兼容现有的做事方式。 第二个是更直接的,并且与其他RDMS系统更加一致。

Nate Zaugg answered 2019-01-10T23:33:58Z

3 votes

它被称为Identity Columns,它只能从oracle Oracle 12c获得

CREATE TABLE identity_test_tab

(

id NUMBER GENERATED ALWAYS AS IDENTITY,

description VARCHAR2 (30)

);

插入Identity Columns的示例如下

INSERT INTO identity_test_tab (description) VALUES ('Just DESCRIPTION');

已创建1行。

你不能像下面这样插入

INSERT INTO identity_test_tab (id, description) VALUES (NULL, 'ID=NULL and DESCRIPTION');

第1行的错误:ORA-32795:无法插入生成的始终   身份栏

INSERT INTO identity_test_tab (id, description) VALUES (999, 'ID=999 and DESCRIPTION');

第1行的错误:ORA-32795:无法插入生成的始终   身份栏

有用的链接

sam answered 2019-01-10T23:34:52Z

1 votes

这是完整的解决方案w.r.t异常/错误处理自动增量,这个解决方案是向后兼容的,将适用于11g&amp; 12c,特别是如果应用程序正在生产中。

请使用适当的表名替换“TABLE_NAME”

--checking if table already exisits

BEGIN

EXECUTE IMMEDIATE 'DROP TABLE TABLE_NAME';

EXCEPTION WHEN OTHERS THEN NULL;

END;

/

--creating table

CREATE TABLE TABLE_NAME (

ID NUMBER(10) PRIMARY KEY NOT NULL,

.

.

.

);

--checking if sequence already exists

BEGIN

EXECUTE IMMEDIATE 'DROP SEQUENCE TABLE_NAME_SEQ';

EXCEPTION WHEN OTHERS THEN NULL;

END;

--creating sequence

/

CREATE SEQUENCE TABLE_NAME_SEQ START WITH 1 INCREMENT BY 1 MINVALUE 1 NOMAXVALUE NOCYCLE CACHE 2;

--granting rights as per required user group

/

GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE_NAME TO USER_GROUP;

-- creating trigger

/

CREATE OR REPLACE TRIGGER TABLE_NAME_TS BEFORE INSERT OR UPDATE ON TABLE_NAME FOR EACH ROW

BEGIN

-- auto increment column

SELECT TABLE_NAME_SEQ.NextVal INTO :New.ID FROM dual;

-- You can also put some other required default data as per need of your columns, for example

SELECT SYS_CONTEXT('USERENV', 'SESSIONID') INTO :New.SessionID FROM dual;

SELECT SYS_CONTEXT('USERENV','SERVER_HOST') INTO :New.HostName FROM dual;

SELECT SYS_CONTEXT('USERENV','OS_USER') INTO :New.LoginID FROM dual;

.

.

.

END;

/

emkays answered 2019-01-10T23:35:21Z

0 votes

这是我在现有表和列(命名id)上执行此操作的方式:

UPDATE table SET id=ROWNUM;

DECLARE

maxval NUMBER;

BEGIN

SELECT MAX(id) INTO maxval FROM table;

EXECUTE IMMEDIATE 'DROP SEQUENCE table_seq';

EXECUTE IMMEDIATE 'CREATE SEQUENCE table_seq START WITH '|| TO_CHAR(TO_NUMBER(maxval)+1) ||' INCREMENT BY 1 NOMAXVALUE';

END;

CREATE TRIGGER table_trigger

BEFORE INSERT ON table

FOR EACH ROW

BEGIN

:new.id := table_seq.NEXTVAL;

END;

ether6 answered 2019-01-10T23:35:42Z

0 votes

FUNCTION GETUNIQUEID_2 RETURN VARCHAR2

AS

v_curr_id NUMBER;

v_inc NUMBER;

v_next_val NUMBER;

pragma autonomous_transaction;

begin

CREATE SEQUENCE sequnce

START WITH YYMMDD0000000001

INCREMENT BY 1

NOCACHE

select sequence.nextval into v_curr_id from dual;

if(substr(v_curr_id,0,6)= to_char(sysdate,'yymmdd')) then

v_next_val := to_number(to_char(SYSDATE+1, 'yymmdd') || '0000000000');

v_inc := v_next_val - v_curr_id;

execute immediate ' alter sequence sequence increment by ' || v_inc ;

select sequence.nextval into v_curr_id from dual;

execute immediate ' alter sequence sequence increment by 1';

else

dbms_output.put_line('exception : file not found');

end if;

RETURN 'ID'||v_curr_id;

END;

kumar venkatesan answered 2019-01-10T23:35:58Z

0 votes

FUNCTION UNIQUE2(

seq IN NUMBER

) RETURN VARCHAR2

AS

i NUMBER := seq;

s VARCHAR2(9);

r NUMBER(2,0);

BEGIN

WHILE i > 0 LOOP

r := MOD( i, 36 );

i := ( i - r ) / 36;

IF ( r < 10 ) THEN

s := TO_CHAR(r) || s;

ELSE

s := CHR( 55 + r ) || s;

END IF;

END LOOP;

RETURN 'ID'||LPAD( s, 14, '0' );

END;

kumar venkatesan answered 2019-01-10T23:36:13Z

-1 votes

oracle在12c中有序列和标识列

[http://www.oracle-base.com/articles/12c/identity-columns-in-oracle-12cr1.php#identity-columns]

我发现了这个,但不确定rdb 7是什么[http://www.oracle.com/technetwork/products/rdb/0307-identity-columns-128126.pdf]

Kalpesh Soni answered 2019-01-10T23:36:50Z

-1 votes

create trigger t1_trigger

before insert on AUDITLOGS

for each row

begin

select t1_seq.nextval into :new.id from dual;

end;

只需要用表名更改表名(AUDITLOGS),用new.column_name更改new.id

abhishek ringsia answered 2019-01-10T23:37:12Z

-2 votes

也许只是尝试这个简单的脚本:

[http://www.hlavaj.sk/ai.php]

结果是:

CREATE SEQUENCE TABLE_PK_SEQ;

CREATE OR REPLACE TRIGGER TR_SEQ_TABLE BEFORE INSERT ON TABLE FOR EACH ROW

BEGIN

SELECT TABLE_PK_SEQ.NEXTVAL

INTO :new.PK

FROM dual;

END;

Martin Hlavaj answered 2019-01-10T23:37:46Z

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值