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

Sus*_*ire 390 sql oracle auto-increment

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

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

Eug*_*vas 555

从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;
Run Code Online (Sandbox Code Playgroud)

触发定义:

CREATE OR REPLACE TRIGGER dept_bir 
BEFORE INSERT ON departments 
FOR EACH ROW

BEGIN
  SELECT dept_seq.NEXTVAL
  INTO   :new.id
  FROM   dual;
END;
/
Run Code Online (Sandbox Code Playgroud)

更新:

IDENTITY 现在可以在Oracle 12c上使用该列:

create table t1 (
    c1 NUMBER GENERATED by default on null as IDENTITY,
    c2 VARCHAR2(10)
    );
Run Code Online (Sandbox Code Playgroud)

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

create table t1 (
    c1 NUMBER GENERATED ALWAYS as IDENTITY(START with 1 INCREMENT by 1),
    c2 VARCHAR2(10)
    );
Run Code Online (Sandbox Code Playgroud)

或者,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));
Run Code Online (Sandbox Code Playgroud)

  • 对于像我这样的oracle新手,'new.id'的'id'部分指的是上表中的'id'列.'new'是一个保留字,指的是创建的新行 (10认同)
  • 我是n00b,你能告诉我`dept_seq`来自哪里! (5认同)
  • 你不需要在触发器中使用 `SELECT .. INTO` 你可以只做 `:new.id := dept_seq.NEXTVAL;`。 (3认同)
  • 创建序列dept_seq; 创建dept_seq ...就像一个表..但在这种情况下,它只能通过dept_seq.NEXTVAL增加一个数字...查看触发器. (2认同)

Jus*_*ave 86

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

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

CREATE SEQUENCE name_of_sequence
  START WITH 1
  INCREMENT BY 1
  CACHE 100;
Run Code Online (Sandbox Code Playgroud)

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

INSERT INTO name_of_table( primary_key_column, <<other columns>> )
  VALUES( name_of_sequence.nextval, <<other values>> );
Run Code Online (Sandbox Code Playgroud)

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

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;
Run Code Online (Sandbox Code Playgroud)

如果您使用的是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;
Run Code Online (Sandbox Code Playgroud)

如果你真的想用 SYS_GUID

CREATE TABLE table_name (
  primary_key_column raw(16) default sys_guid() primary key,
  <<other columns>>
)
Run Code Online (Sandbox Code Playgroud)

  • CACHE 100:关键字将下一个100个数字提取到内存中.通常情况下,只要SEQUENCE的值发生变化,就会将其保存到数据库中,如果缓存它,只有在缓存的数据库耗尽时才会保存和检索SEQUENCE.为您带来显着的性能提升,但如果数据库失败,您将丢失您甚至不使用的所有缓存值. (3认同)
  • `SYS_GUID()`是`RAW(16)`,而不是32. (2认同)
  • @turbanoff - 很好的捕获.更新了我的回答.`SYS_GUID`文档声明了一个让我困惑的`raw(32)`. (2认同)

Nis*_*sar 49

在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)
);
Run Code Online (Sandbox Code Playgroud)

在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;
/
Run Code Online (Sandbox Code Playgroud)

  • `WHEN(new.MAP_ID IS NULL)`不在接受的答案中.Upvoted. (5认同)
  • @JonHeller我个人说“ IDENTITY”示例在此答案中更加清晰。 (2认同)

Mar*_*son 32

这有三种口味:

  1. 数字.简单地增加数值,例如1,2,3,....
  2. GUID.全局univeral标识符,作为RAW数据类型.
  3. 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;
/
Run Code Online (Sandbox Code Playgroud)

更新:

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

create table mytable(id number default mysequence.nextval);
create table mytable(id number generated as identity);
Run Code Online (Sandbox Code Playgroud)

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


Phi*_*ler 7

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

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

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


Cor*_*ola 7

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

以下文章介绍了如何使用它:

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

  • 虽然此链接可能会回答这个问题,但最好在此处包含答案的基本部分并提供参考链接.如果链接的页面发生更改,则仅链接的答案可能会无效. (5认同)

N J*_*N J 5

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

CREATE TABLE <table_name> 
(emp_id RAW(16) DEFAULT SYS_GUID() PRIMARY KEY,
name VARCHAR2(30));
Run Code Online (Sandbox Code Playgroud)

现在,您的emp_id列将接受"全局唯一标识符值".您可以通过忽略emp_id列来在表中插入值.

INSERT INTO <table_name> (name) VALUES ('name value');
Run Code Online (Sandbox Code Playgroud)

因此,它会为您的emp_id列插入唯一值.


Nat*_*ugg 5

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

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

    CREATE TABLE MyTable(ID NUMBER DEFAULT MyTable_Seq.NEXTVAL,...)

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

    CREATE TABLE MyTable的(ID号生成为IDENTITY ...)

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


sam*_*sam 5

它被调用Identity Columns并且只能从 oracle Oracle 12c 获得

CREATE TABLE identity_test_tab
(
   id            NUMBER GENERATED ALWAYS AS IDENTITY,
   description   VARCHAR2 (30)
);
Run Code Online (Sandbox Code Playgroud)

插入的示例Identity Columns如下

INSERT INTO identity_test_tab (description) VALUES ('Just DESCRIPTION');
Run Code Online (Sandbox Code Playgroud)

已创建 1 行。

你不能像下面那样插入

INSERT INTO identity_test_tab (id, description) VALUES (NULL, 'ID=NULL and DESCRIPTION');
Run Code Online (Sandbox Code Playgroud)

第 1 行的错误:ORA-32795:无法插入生成的始终标识列

INSERT INTO identity_test_tab (id, description) VALUES (999, 'ID=999 and DESCRIPTION');
Run Code Online (Sandbox Code Playgroud)

第 1 行的错误:ORA-32795:无法插入生成的始终标识列

有用的链接