Oracle에는 버전 11g까지 AUTO_INCREMENT의 개념이없는 것으로 보입니다.
Oracle 11g에서 자동 증분처럼 동작하는 열을 어떻게 만들 수 있습니까?
Oracle에는 버전 11g까지 AUTO_INCREMENT의 개념이없는 것으로 보입니다.
Oracle 11g에서 자동 증분처럼 동작하는 열을 어떻게 만들 수 있습니까?
답변:
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;
/
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));
dept_seq
입니다. 어디에서 왔는지 알려주세요 !
SELECT .. INTO
할 수있는 방아쇠 에 사용할 필요가 없습니다 :new.id := dept_seq.NEXTVAL;
.
SYS_GUID
GUID (전역 적으로 고유 한 ID)를 반환합니다. A SYS_GUID
는입니다 RAW(16)
. 증분 숫자 값을 생성하지 않습니다.
증분 숫자 키를 만들려면 시퀀스를 만들어야합니다.
CREATE SEQUENCE name_of_sequence
START WITH 1
INCREMENT BY 1
CACHE 100;
그런 다음 INSERT
진술서 에서 해당 순서를 사용하십시오 .
INSERT INTO name_of_table( primary_key_column, <<other columns>> )
VALUES( name_of_sequence.nextval, <<other values>> );
또는 시퀀스를 사용하여 기본 키 값을 자동으로 채우는 트리거를 정의 할 수 있습니다.
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,
<<other columns>>
)
CACHE 100; in CREATE SEQUENCE name_of_sequence START WITH 1 INCREMENT BY 1 CACHE 100;
합니까?
SYS_GUID()
는 RAW(16)
32가 아닌 a 입니다 .
SYS_GUID
문서는 선언 raw(32)
저를 혼동하는합니다.
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)
);
그리고 오라클에서 (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;
/
IDENTITY
으로이 대답에서 예가 훨씬 명확 하다고 말합니다 .
WHEN (new.MAP_ID IS NULL)
허용 대답에 있지 않습니다. 공감.
WHEN ( new.MAP_ID is null)
이 경우에 좋은 코드가 아닙니다 이미 허용 대답에서 @ABCade에 의해 코멘트 섹션에 설명되어 있습니다 .. 읽기가)
CREATE OR REPLACE TRIGGER
를 실행 END;
하면 "바인드 입력"창이 나타납니다. "적용"을 클릭하고 해당 창에서 다른 작업을 수행하지 않고 ALTER TRIGGER
명령 을 실행하면 모든 것이 잘되지만 프로그래밍 방식으로 해당 팝업을 제거하고 모든 것을 함께 실행할 수있는 방법이 있었으면 좋겠습니다. 당신이 그것을 모두 시도한다면, 당신은 PLS-00103: Encountered the symbol 'ALTER'
그것을 얻지 못하고 좋아하지도 않습니다 EXECUTE IMMEDIATE
(같은 오류, Encountered the symbol 'EXECUTE'
대신 말해보십시오 ).
[42000][907] ORA-00907: missing right parenthesis
Oracle 12c 버전을 실행할 때 얻었습니다 . 어떤 아이디어?
세 가지 맛이 있습니다.
RAW
데이터 형식 으로 사용되는 전역 범용 식별자 .x
ID 열입니다. 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);
첫 번째는 전통적인 방식으로 시퀀스를 사용합니다. 두 번째는 내부적으로 가치를 관리합니다.
SQL Server ID 열과 같은 열을 의미한다고 가정합니까?
Oracle에서는 SEQUENCE를 사용하여 동일한 기능을 수행합니다. 좋은 링크를 찾아 여기에 게시 할 수 있는지 확인하겠습니다.
업데이트 : 직접 찾은 것처럼 보입니다. 어쨌든 링크는 다음과 같습니다. http://www.techonthenet.com/oracle/sequences.php
Oracle Database 12c는 자동 증분 (시스템 생성) 열인 Identity를 도입했습니다. 이전 데이터베이스 버전 (11g까지)에서는 일반적으로 시퀀스와 트리거를 만들어 Identity를 구현합니다. 12c부터는 고유 한 테이블을 생성하고 ID로 생성해야하는 열을 정의 할 수 있습니다.
다음 기사에서는이를 사용하는 방법에 대해 설명합니다.
Trigger
그리고 Sequence
당신이 누구나 쉽게 / 기억 / 읽고 이해할 수있는 일련 번호를하고자 할 때 사용할 수 있습니다. 그러나 이런 식으로 ID 열 (emp_id와 같은)을 관리하지 않고이 열의 값이 그다지 중요하지 않은 경우 SYS_GUID()
테이블 생성에서이를 사용 하여 자동 증분을 얻을 수 있습니다 .
CREATE TABLE <table_name>
(emp_id RAW(16) DEFAULT SYS_GUID() PRIMARY KEY,
name VARCHAR2(30));
이제 emp_id
열에 "글로벌 고유 식별자 값"이 적용됩니다. 이와 같이 emp_id 열을 무시하여 테이블에 값을 삽입 할 수 있습니다.
INSERT INTO <table_name> (name) VALUES ('name value');
따라서 emp_id
열에 고유 한 값을 삽입합니다 .
SYS_GUID()
의 ID 값도?
Oracle 12c부터는 다음 두 가지 방법 중 하나로 ID 열이 지원됩니다.
시퀀스 + 테이블 -이 솔루션에서는 평상시처럼 시퀀스를 생성 한 후 다음 DDL을 사용합니다.
테이블 MyTable 만들기 (ID NUMBER DEFAULT MyTable_Seq.NEXTVAL , ...)
테이블 만 -이 솔루션에서는 시퀀스가 명시 적으로 지정되지 않습니다. 다음과 같은 DDL을 사용합니다.
CREATE TABLE MyTable (ID 번호가 ID로 생성됨 , ...)
첫 번째 방법을 사용하면 기존 방식으로 이전 버전과 호환됩니다. 두 번째는 조금 더 간단하고 나머지 RDMS 시스템과 더 일치합니다.
그것은이라고 Identity Columns
하며이 가능합니다 에만 오라클 오라클 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 : 생성 된 상시 식별 열에 삽입 할 수 없습니다.
다음은 자동 증분에 대한 완전한 솔루션 wrt 예외 / 오류 처리입니다.이 솔루션은 이전 버전과 호환되며 특히 응용 프로그램이 프로덕션 환경 인 경우 11g 및 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;
/
이것이 기존 테이블과 열 (이름이 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;
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;
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;
오라클은 12c에 시퀀스 및 ID 열이 있습니다.
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
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를 변경하면됩니다.
아마도이 간단한 스크립트를 사용해보십시오.
결과는 다음과 같습니다
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;
select
최신 Oracle 버전이 필요하지 않습니다 . 간단히 사용할 수 있습니다:new.pk := TABLE_PK_SEQ.NEXTVAL
BEFORE INSERT
테이블 에서 트리거를 생성하고 시퀀스에서 값을