在Oracle中似乎没有AUTO_INCREMENT的概念,直到并且包括版本11g。
如何在Oracle 11g中创建一个行为像自动递增的列?
在Oracle中似乎没有AUTO_INCREMENT的概念,直到并且包括版本11g。
如何在Oracle 11g中创建一个行为像自动递增的列?
当前回答
在Oracle 11g中没有“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;
/
更新:
IDENTITY列现在可以在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));
其他回答
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;
在Oracle 11g中没有“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;
/
更新:
IDENTITY列现在可以在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));
从Oracle 12c开始,有两种方式支持Identity列:
序列+表-在这个解决方案中,您仍然像往常一样创建一个序列,然后使用以下DDL: 创建MyTable (ID NUMBER DEFAULT MyTable_Seq.)NEXTVAL, …) 仅限表-在此解决方案中没有显式指定序列。您将使用以下DDL: 创建表MyTable (ID号作为身份生成,…)
如果您使用第一种方式,那么它与现有的做事方式向后兼容。第二个更简单一些,与其他RDMS系统更内联。
这里有三种口味:
数字。简单递增的数值,例如1,2,3,.... GUID。全局通用标识符,作为RAW数据类型。 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);
第一个是传统的序列;第二个在内部管理值。
查询如何在oracle中创建自动增量。在下面的查询中,每当插入新行时,列值将自动递增
CREATE TABLE table1(
id RAW(16) NOT NULL ENABLE,
incrmnt NUMBER(10,0) GENERATED ALWAYS AS IDENTITY
MINVALUE 1 MAXVALUE 999999999999999999999999999 INCREMENT BY 1 START WITH 1 NOORDER NOCYCLE NOT NULL ENABLE,
CONSTRAINT PK_table1 PRIMARY KEY (id) ENABLE);