Görünüşe göre Oracle'da 11g sürümüne kadar olan AUTO_INCREMENT konsepti yok.
Oracle 11g'de otomatik artış gibi davranan bir sütunu nasıl oluşturabilirim?
Görünüşe göre Oracle'da 11g sürümüne kadar olan AUTO_INCREMENT konsepti yok.
Oracle 11g'de otomatik artış gibi davranan bir sütunu nasıl oluşturabilirim?
Yanıtlar:
"AUTO_INCREMENT" Oracle'da "kimlik" sütunlarında diye bir şey yoktur , Oracle 11g itibariyle . Ancak, bir dizi ve bir tetikleyici ile kolayca modelleyebilirsiniz:
Tablo tanımı:
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;
Tetikleyici tanımı:
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
sütunu artık Oracle 12c'de kullanılabilir:
create table t1 (
c1 NUMBER GENERATED by default on null as IDENTITY,
c2 VARCHAR2(10)
);
veya başlangıç ve artış değerlerini GENERATED ALWAYS
belirterek kimlik sütununa ekleme yapılmasını da önler ( ) (yine yalnızca Oracle 12c +)
create table t1 (
c1 NUMBER GENERATED ALWAYS as IDENTITY(START with 1 INCREMENT by 1),
c2 VARCHAR2(10)
);
Alternatif olarak, Oracle 12 ayrıca bir dizinin varsayılan değer olarak kullanılmasına izin verir:
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
geldiğini söyleyebilir misin !
SELECT .. INTO
tetikleyicide kullanmanıza gerek yoktur :new.id := dept_seq.NEXTVAL;
.
SYS_GUID
bir GUID döndürür - global olarak benzersiz bir kimlik. A SYS_GUID
bir RAW(16)
. Artan bir sayısal değer oluşturmaz.
Artan bir sayısal anahtar oluşturmak istiyorsanız, bir sıra oluşturmak istersiniz.
CREATE SEQUENCE name_of_sequence
START WITH 1
INCREMENT BY 1
CACHE 100;
Daha sonra ya bu diziyi kullanmak istiyorsunuz INSERT
açıklamada
INSERT INTO name_of_table( primary_key_column, <<other columns>> )
VALUES( name_of_sequence.nextval, <<other values>> );
Veya diziyi kullanarak birincil anahtar değerini otomatik olarak dolduran bir tetikleyici tanımlayabilirsiniz
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 veya üstünü kullanıyorsanız, tetikleyiciyi biraz basitleştirebilirsiniz.
CREATE OR REPLACE TRIGGER trigger_name
BEFORE INSERT ON table_name
FOR EACH ROW
BEGIN
:new.primary_key_column := name_of_sequence.nextval;
END;
Gerçekten kullanmak istiyorsan 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 değil.
SYS_GUID
Dokümantasyon bir beyan raw(32)
beni karıştı hangi.
Oracle 12c ve sonrasında,
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)
);
Ve Oracle'da (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
örnek bu cevapta çok daha net olduğunu söylüyorum .
WHEN (new.MAP_ID IS NULL)
Kabul edilen cevap değildir. Upvoted.
WHEN ( new.MAP_ID is null)
bu durumda iyi bir kod değildir ve zaten yorum bölümünde @ABCade tarafından kabul edilen cevap altında açıklanmıştır .. bir okuma var;)
CREATE OR REPLACE TRIGGER
için END;
, bir "bağlayan Enter" penceresi çıkacaktır. "Uygula" yı tıklar ve o pencerede başka bir şey yapmaz ve sonra ALTER TRIGGER
komutu çalıştırırsam , her şey yolundadır, ancak programlı olarak bu pop-up'dan kurtulmanın ve her şeyi birlikte çalıştırmanın bir yolu olsaydı. Tamamen denerseniz, alırsınız PLS-00103: Encountered the symbol 'ALTER'
ve beğenmezsiniz EXECUTE IMMEDIATE
(aynı hata, bunun Encountered the symbol 'EXECUTE'
yerine söyler ).
[42000][907] ORA-00907: missing right parenthesis
Oracle 12c için sürümü çalıştırırken aldım . Herhangi bir fikir ?
İşte üç lezzet:
RAW
veri türü olarak global olarak tek yönlü tanımlayıcı .x
kimlik sütunu. Değiştirin FOO
örneklerin her birinde tablo adınızı.
-- 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;
/
Güncelleme:
Oracle 12c, tetikleyicilere bağlı olmayan bu iki değişkeni sunar:
create table mytable(id number default mysequence.nextval);
create table mytable(id number generated as identity);
Birincisi geleneksel şekilde bir dizi kullanır; ikincisi değeri dahili olarak yönetir.
SQL Server kimlik sütunu gibi bir sütun mu demek istiyorsunuz?
Oracle'da, aynı işlevselliği elde etmek için bir SEQUENCE kullanırsınız. İyi bir bağlantı bulup bulamayacağımı göreceğim.
Güncelleme: Görünüşe göre kendiniz buldunuz. Yine de bağlantı şu şekildedir: http://www.techonthenet.com/oracle/sequences.php
Oracle Database 12c, otomatik artan (sistem tarafından oluşturulan) bir sütun olan Identity'yi tanıttı. Önceki veritabanı sürümlerinde (11g'ye kadar), genellikle bir Dizi ve Tetikleyici oluşturarak bir Kimlik uygularsınız. 12c'den itibaren kendi tablonuzu oluşturabilir ve bir Kimlik olarak oluşturulması gereken sütunu tanımlayabilirsiniz.
Aşağıdaki makalede bunun nasıl kullanılacağı açıklanmaktadır:
Trigger
ve Sequence
herkesin kolayca okuyabileceği / hatırlayabileceği / anlayabileceği seri numara istediğinizde kullanılabilir. Ancak ID Sütunu'nu (emp_id gibi) bu şekilde yönetmek istemiyorsanız ve bu sütunun değeri çok önemli değilse, SYS_GUID()
Otomatik Artış'ı bu şekilde elde etmek için Tablo Oluşturma'da kullanabilirsiniz .
CREATE TABLE <table_name>
(emp_id RAW(16) DEFAULT SYS_GUID() PRIMARY KEY,
name VARCHAR2(30));
Artık emp_id
sütununuz "global olarak benzersiz tanımlayıcı değeri" kabul edecek. emp_id sütununu bu şekilde yoksayarak tabloya değer ekleyebilirsiniz.
INSERT INTO <table_name> (name) VALUES ('name value');
Böylece, emp_id
Sütununuza benzersiz bir değer katacaktır.
SYS_GUID()
onun kimliği değerleri de?
Oracle 12c'den başlayarak, Kimlik sütunlarını iki yoldan biriyle destekleyin:
Sıra + Tablo - Bu çözümde normalde yaptığınız gibi bir sıra oluşturmaya devam edersiniz, ardından aşağıdaki DDL'yi kullanırsınız:
TABLO OLUŞTURMA OLUŞTUR (ID NUMBER VARSAYILAN MyTable_Seq.NEXTVAL , ...)
Yalnızca Tablo - Bu çözümde hiçbir sıra açıkça belirtilmez. Aşağıdaki DDL'yi kullanırsınız:
TABLO OLUŞTURMA ( KİMLİK OLARAK ÜRETİLEN KİMLİK NUMARASI , ...)
İlk yolu kullanırsanız, mevcut iş yapma yöntemiyle geriye dönük uyumludur. İkincisi biraz daha basittir ve diğer RDMS sistemleri ile daha fazla satır içi.
denir Identity Columns
ve yalnızca Oracle Oracle 12c'den alınabilir
CREATE TABLE identity_test_tab
(
id NUMBER GENERATED ALWAYS AS IDENTITY,
description VARCHAR2 (30)
);
Identity Columns
aşağıdaki gibi içine ekleme örneği
INSERT INTO identity_test_tab (description) VALUES ('Just DESCRIPTION');
1 satır oluşturuldu.
aşağıdaki gibi ekleyemezsiniz
INSERT INTO identity_test_tab (id, description) VALUES (NULL, 'ID=NULL and DESCRIPTION');
Satır 1'deki HATA: ORA-32795: oluşturulan her zaman kimlik sütununa eklenemiyor
INSERT INTO identity_test_tab (id, description) VALUES (999, 'ID=999 and DESCRIPTION');
Satır 1'deki HATA: ORA-32795: oluşturulan her zaman kimlik sütununa eklenemiyor
İşte otomatik artış için istisna / hata işleme ile komple çözüm, bu çözüm geriye dönük olarak uyumludur ve özellikle uygulama üretimde ise 11g ve 12c'de çalışacaktır.
Lütfen 'TABLE_NAME' yerine uygun tablo adınızı yazın
--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;
/
Varolan bir tablo ve sütun (id adlı) böyle yaptım:
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;
oracle 12c dizileri ve kimlik sütunları vardır
http://www.oracle-base.com/articles/12c/identity-columns-in-oracle-12cr1.php#identity-columns
Bunu buldum ama rdb 7'nin ne olduğundan emin değilim 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;
sadece tablo adını (AUDITLOGS) tablo adınızla ve new.id ile new.column_name değiştirmeliyim
Belki de şu basit komut dosyasını deneyin:
Sonuç:
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
modern Oracle sürümlerinde ihtiyacınız yok . Basitçe kullanabilirsiniz:new.pk := TABLE_PK_SEQ.NEXTVAL
BEFORE INSERT
Otomatik artış oluşturmak için masada bir tetikleyici oluşturabilir ve değerleri bir diziden çıkarabilirsiniz