Comment créer un id avec auto INCREMENT sur Oracle?

il semble qu'il n'y ait pas de concept D'AUTO_ incrément dans Oracle, jusqu'à et y compris la version 11g.

Comment puis-je créer une colonne qui se comporte comme auto increment dans Oracle 11g?

319
demandé sur Gurwinder Singh 2012-07-02 19:09:48

16 réponses

il n'y a pas de colonnes" auto_ incrément "ou" identité "dans Oracle à partir de Oracle 11g . Cependant, vous pouvez modéliser facilement avec une séquence et un déclencheur:

définition de la Table:

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;

définition de déclenchement:

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

BEGIN
  SELECT dept_seq.NEXTVAL
  INTO   :new.id
  FROM   dual;
END;
/

mise à jour:

IDENTITY colonne est maintenant disponible sur Oracle 12c:

create table t1 (
    c1 NUMBER GENERATED by default on null as IDENTITY,
    c2 VARCHAR2(10)
    );

ou spécifier les valeurs de départ et d'incrément, empêchant également toute insertion dans la colonne identité ( GENERATED ALWAYS ) (encore une fois, Oracle 12c + seulement)

create table t1 (
    c1 NUMBER GENERATED ALWAYS as IDENTITY(START with 1 INCREMENT by 1),
    c2 VARCHAR2(10)
    );
467
répondu Eugenio Cuevas 2017-05-08 07:40:03

SYS_GUID renvoie un GUID-- un identifiant unique au niveau mondial. Un SYS_GUID est un RAW(16) . Il ne génère pas de valeur numérique incrémentielle.

si vous voulez créer une clé numérique incrémente, vous voulez créer une séquence.

CREATE SEQUENCE name_of_sequence
  START WITH 1
  INCREMENT BY 1
  CACHE 100;

vous utiliseriez alors cette séquence dans votre INSERT déclaration

INSERT INTO name_of_table( primary_key_column, <<other columns>> )
  VALUES( name_of_sequence.nextval, <<other values>> );

Ou vous pouvez définir un déclencheur qui popule automatiquement la valeur de la clé primaire en utilisant la séquence

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;

si vous utilisez Oracle 11.1 ou plus tard, vous pouvez simplifier un peu la gâchette""

CREATE OR REPLACE TRIGGER trigger_name
  BEFORE INSERT ON table_name
  FOR EACH ROW
BEGIN
  :new.primary_key_column := name_of_sequence.nextval;
END;

Si vous voulez vraiment utiliser SYS_GUID

CREATE TABLE table_name (
  primary_key_column raw(16) default sys_guid() primary key,
  <<other columns>>
)
78
répondu Justin Cave 2013-10-09 12:28:08

dans Oracle 12c onward vous pourriez faire quelque chose comme,

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)
);

et dans Oracle (pré 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;
/
40
répondu Nisar 2018-03-06 16:03:43

Voici trois saveurs:

  1. numérique . Valeur numérique croissante Simple, par exemple 1,2,3....
  2. GUID . identificateur universel mondial, en tant que type de données RAW .
  3. GUID (string) . Même que ci-dessus, mais comme une chaîne qui pourrait être plus facile à gérer dans certaines langues.

x est le colonne d'identité. Remplacez FOO par le nom de votre table dans chacun des exemples.

-- 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;
/

mise à jour:

Oracle 12c présente ces deux variantes qui ne dépendent pas de déclencheurs:

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

le premier utilise une séquence de manière traditionnelle; le second gère la valeur en interne.

31
répondu Mark Harrison 2016-02-24 16:38:16

si vous voulez dire une colonne comme la colonne SQL Server identity?

dans Oracle, vous utilisez une séquence pour obtenir la même fonctionnalité. Je vais voir si je peux trouver un bon lien et le poster ici.

mise à jour: on dirait que vous l'avez trouvé vous-même. Voici le lien de toute façon: http://www.techonthenet.com/oracle/sequences.php

7
répondu Phil Sandler 2010-01-12 23:44:50

Base de données Oracle 12c introduit Identité, un auto-incrémental (généré par le système) de la colonne. Dans les versions précédentes de la base de données (jusqu'à 11g), vous implémentez habituellement une identité en créant une séquence et un déclencheur. À partir de 12c, vous pouvez créer votre propre Table et définir la colonne qui doit être générée comme une identité.

L'article suivant explique comment l'utiliser:

colonnes d'Identité - Une nouvelle entrée dans la Base de données Oracle 12c

7
répondu Corrado Piola 2017-04-05 13:06:48

Trigger et Sequence peut être utilisé lorsque vous souhaitez sérialisé nombre que n'importe qui peut facilement lire/souvenir/comprendre. Mais si vous ne voulez pas gérer la colonne ID (comme emp_id) de cette façon, et la valeur de cette colonne n'est pas beaucoup considérable, vous pouvez utiliser SYS_GUID() à la création de Table pour obtenir L'incrément automatique comme ceci.

CREATE TABLE <table_name> 
(emp_id RAW(16) DEFAULT SYS_GUID() PRIMARY KEY,
name VARCHAR2(30));

maintenant votre colonne emp_id acceptera"global unique identifier value". vous pouvez insérer la valeur dans le tableau, en ignorant emp_id colonne comme ceci.

INSERT INTO <table_name> (name) VALUES ('name value');

ainsi, il insérera une valeur unique à votre colonne emp_id .

5
répondu N J 2014-01-18 06:08:37

à partir D'Oracle 12c, il y a deux façons de prendre en charge les colonnes D'identité:

  1. séquence + Table - dans cette solution vous créez toujours une séquence comme vous le feriez normalement, puis vous utilisez le DDL suivant:

    créer TABLE MyTable (ID NUMBER DEFAULT MyTable_Seq.NEXTVAL , ...)

  2. Table Only - Dans cette solution, aucune séquence n'est explicitement spécifié. Vous devez utiliser le DDL suivant:

    CREATE TABLE MyTable (ID NUMBER GENERATED AS IDENTITY , ...)

si vous utilisez la première voie, elle est rétrograde compatible avec la manière existante de faire les choses. Le second est un peu plus simple et s'inscrit davantage dans le droit fil des autres systèmes de SGDR.

4
répondu Nate Zaugg 2016-02-24 15:53:29

il est appelé Identity Columns et il est disponible seulement de oracle Oracle 12c

CREATE TABLE identity_test_tab
(
   id            NUMBER GENERATED ALWAYS AS IDENTITY,
   description   VARCHAR2 (30)
);

exemple d'insertion dans Identity Columns comme ci-dessous

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

1 ligne créée.

vous ne pouvez pas insérer comme ci-dessous

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

erreur à la ligne 1: ORA-32795: ne peut pas insérer dans un généré toujours colonne d'identité

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

erreur à la ligne 1: ORA-32795: ne peut pas insérer dans un généré toujours colonne identité

lien utile

3
répondu sam 2017-03-10 12:44:26

Voici la solution complète W. R. t traitement des exceptions/erreurs pour l'incrément automatique, Cette solution est rétrocompatible et fonctionnera sur 11g & 12c, en particulier si l'application est en production.

veuillez remplacer "TABLE_NAME" par votre nom de table approprié

--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;
/
1
répondu emkays 2016-02-17 11:12:47
0
répondu Kalpesh Soni 2013-08-27 21:47:23

C'est comme ça que je l'ai fait sur une table et une colonne existantes (nommée 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;
0
répondu ether6 2017-01-18 23:06:13
  create trigger t1_trigger
  before insert on AUDITLOGS
  for each row
   begin
     select t1_seq.nextval into :new.id from dual;
   end;

seulement je dois juste changer le nom de la table (les carnets D'audit) avec votre nom de table et nouveau.id with new.nom de la colonne

-1
répondu abhishek ringsia 2015-09-21 06:46:21
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;
-1
répondu kumar venkatesan 2017-08-02 11:22:07
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;
-1
répondu kumar venkatesan 2017-08-02 11:25:31

peut-être juste essayer ce script simple:

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

résultat:

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;
-2
répondu Martin Hlavaj 2015-09-02 09:24:22