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)
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)
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)
Mar*_*son 32
这有三种口味:
RAW
数据类型.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)
第一个使用传统方式的序列; 第二个在内部管理价值.
假设您的意思是像SQL Server标识列一样的列?
在Oracle中,您使用SEQUENCE来实现相同的功能.我会看看我是否能找到一个好的链接并在此发布.
更新:看起来你自己找到了它.无论如何,这是链接:http: //www.techonthenet.com/oracle/sequences.php
Oracle Database 12c引入了Identity,一个自动增量(系统生成的)列.在以前的数据库版本中(直到11g),您通常通过创建序列和触发器来实现Identity.从12c开始,您可以创建自己的表并定义必须作为标识生成的列.
以下文章介绍了如何使用它:
标识列 - Oracle Database 12c中的新条目
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
列插入唯一值.
从Oracle 12c开始,可以通过以下两种方式之一支持Identity列:
序列+表 - 在此解决方案中,您仍然可以像往常一样创建序列,然后使用以下DDL:
CREATE TABLE MyTable(ID NUMBER DEFAULT MyTable_Seq.NEXTVAL,...)
仅表 - 在此解决方案中,未明确指定序列.您将使用以下DDL:
CREATE TABLE MyTable的(ID号生成为IDENTITY ...)
如果您使用第一种方式,它向后兼容现有的做事方式.第二个是更直接的,并且与其他RDMS系统更加一致.
它被调用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:无法插入生成的始终标识列
归档时间: |
|
查看次数: |
891199 次 |
最近记录: |