由于几个关键原因,尤其是在处理主要键时,Auto_increment在Oracle上很重要。 Oracle使用序列和身份列来实现此功能。在此博客中,让我们探索如何在Oracle SQL上使用Auto_increment创建ID。
目录:
可用于在Oracle SQL上进行自动插入的方法
在进入方法之前,让我们创建一个员工表,我们将用于所有示例。
CREATE TABLE Employees (
Employee_id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
Employee_dept NVARCHAR2(50),
Salary DECIMAL(10,2)
);
方法1:使用Oracle SQL上的身份列
我们可以定义身份列以自动生成ID字段的唯一值。
句法:
-- Creating a table with Ian IDENTITY Column
CREATE TABLE table_name (
column_name NUMBER GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY
[ START WITH start_value ]
[ INCREMENT BY increment_value ]
[ MINVALUE min_value | NOMINVALUE ]
[ MAXVALUE max_value | NOMAXVALUE ]
[ CYCLE | NOCYCLE ]
[ CACHE cache_size | NOCACHE ]
PRIMARY KEY,
other_column_name column_type(size),
...
);
-- For inserting the data
INSERT INTO table_name (column2, column3, ...) VALUES (value2, value3, ...);
-- To display data from the table
SELECT * FROM table_name;
例子:
-- Create the employees table with IDENTITY Column
CREATE TABLE Employees (
Employee_id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
Employee_dept NVARCHAR2(50),
Salary DECIMAL(10,2)
);
-- Inserting the data into the Employee table
INSERT INTO Employees (Employee_dept, Salary) VALUES ('HR', 50000.00);
INSERT INTO Employees (Employee_dept, Salary) VALUES ('Finance', 60000.50);
INSERT INTO Employees (Employee_dept, Salary) VALUES ('IT', 75000.75);
-- To display the data
SELECT * FROM Employees;
输出:

解释: 我们可以使用生成的身份来自动为员工_ID生成唯一的值。
方法2:使用序列并在Oracle SQL上触发
序列是一个Oracle数据库SQL对象,它在顺序中生成唯一的数字值。它用于模拟自动插入。
句法:
-- Creating a table
CREATE TABLE table_name (
column_name NUMBER PRIMARY KEY,
other_column_name column_type(size),
...
);
-- Create a Sequence
CREATE SEQUENCE sequence_name
START WITH start_value
INCREMENT BY increment_value
[ MINVALUE min_value | NOMINVALUE ]
[ MAXVALUE max_value | NOMAXVALUE ]
[ CYCLE | NOCYCLE ]
[ CACHE cache_size | NOCACHE ];
-- Create a TRIGGER to AUTO-Assign ID
CREATE OR REPLACE TRIGGER trigger_name
BEFORE INSERT ON table_name
FOR EACH ROW
BEGIN
IF :NEW.column_name IS NULL THEN
SELECT sequence_name.NEXTVAL INTO :NEW.column_name FROM dual;
END IF;
END;
/
-- Insert the data into the table
INSERT INTO table_name (column2, column3, ...) VALUES (value2, value3, ...);
-- Display data from the table
例子:
-- Create the Employee table
CREATE TABLE Employees (
Employee_id NUMBER PRIMARY KEY,
Employee_dept NVARCHAR2(50),
Salary DECIMAL(10,2)
);
-- Create a sequence for Employee_id
CREATE SEQUENCE employee_seq
START WITH 1
INCREMENT BY 1
NOCACHE
NOCYCLE;
-- Create a trigger for Employee_id
CREATE OR REPLACE TRIGGER employees_before_insert
BEFORE INSERT ON Employees
FOR EACH ROW
BEGIN
IF :NEW.Employee_id IS NULL THEN
SELECT employee_seq.NEXTVAL INTO :NEW.Employee_id FROM dual;
END IF;
END;
/
-- Inserting the data into Employees table
INSERT INTO Employees (Employee_dept, Salary) VALUES ('HR', 50000.00);
INSERT INTO Employees (Employee_dept, Salary) VALUES ('Finance', 60000.50);
INSERT INTO Employees (Employee_dept, Salary) VALUES ('IT', 75000.75);
-- Displaying the Employee table
SELECT * FROM Employees;
输出:

解释: 触发器自动从雇员_seq分配了员工_id值。
方法3:使用Oracle SQL上默认的序列
该方法利用序列与默认关键字结合使用,从而消除了对触发的需求。
句法:
-- Create a table
CREATE TABLE table_name (
column_name NUMBER DEFAULT sequence_name.NEXTVAL PRIMARY KEY,
other_column_name column_type(size),
...
);
-- For creating a SEQUENCE
CREATE SEQUENCE sequence_name
START WITH start_value
INCREMENT BY increment_value
[ MINVALUE min_value | NOMINVALUE ]
[ MAXVALUE max_value | NOMAXVALUE ]
[ CYCLE | NOCYCLE ]
[ CACHE cache_size | NOCACHE ];
--Inserting data into the table
INSERT INTO table_name (column2, column3, ...) VALUES (value2, value3, ...);
-- To display the data
SELECT * FROM table_name;
例子:
--This sequence creates unique Employee_id values automatically
CREATE SEQUENCE employee_seq
START WITH 1
INCREMENT BY 1
NOCYCLE
NOCACHE;
-- Create the Employees table
CREATE TABLE Employees (
Employee_id NUMBER DEFAULT employee_seq.NEXTVAL PRIMARY KEY,
Employee_dept NVARCHAR2(50),
Salary DECIMAL(10,2)
);
--Inserting data into Employees table
INSERT INTO Employees (Employee_dept, Salary) VALUES ('BDT', 55000.00);
INSERT INTO Employees (Employee_dept, Salary) VALUES ('TRA', 33000.00);
INSERT INTO Employees (Employee_dept, Salary) VALUES ('TCW', 75000.00);
--To display the table
SELECT * FROM Employees;
输出:

解释: 该序列会自动创建唯一的员工_id值。
方法4:在Oracle SQL上使用Max(ID)之前使用a之前插入触发器
此方法通过查找最大现有ID并添加1来生成自动INCREMENT ID。
句法:
--Create an Employee table
CREATE TABLE table_name (
column_name NUMBER PRIMARY KEY,
other_column_name column_type(size),
...
);
--Create a BEFORE INSERT Trigger
CREATE OR REPLACE TRIGGER trigger_name
BEFORE INSERT ON table_name
FOR EACH ROW
BEGIN
IF :NEW.column_name IS NULL THEN
SELECT COALESCE(MAX(column_name), 0) + 1 INTO :NEW.column_name FROM table_name;
END IF;
END;
/
--Insert the data into the table
INSERT INTO table_name (column2, column3, ...) VALUES (value2, value3, ...);
--To display the data
SELECT * FROM table_name;
例子:
-- Create an Employee table
CREATE TABLE Employees (
Employee_id NUMBER PRIMARY KEY,
Employee_dept NVARCHAR2(50),
Salary DECIMAL(10,2)
);
--Create a BEFORE INSERT TRIGGER
CREATE OR REPLACE TRIGGER employees_before_insert
BEFORE INSERT ON Employees
FOR EACH ROW
BEGIN
IF :NEW.Employee_id IS NULL THEN
SELECT COALESCE(MAX(Employee_id), 0) + 1 INTO :NEW.Employee_id FROM Employees;
END IF;
END;
/
--Insert some values
INSERT INTO Employees (Employee_dept, Salary) VALUES ('BDT', 55000.00);
INSERT INTO Employees (Employee_dept, Salary) VALUES ('TRA', 33000.00);
INSERT INTO Employees (Employee_dept, Salary) VALUES ('TCW', 75000.00);
--To display the table
SELECT * FROM Employees;
输出:

解释: 这触发会自动创建一个雇员_ID。
方法5:使用Oracle SQL的GUID
GUID(全球唯一标识符)是一种独特的标识符,用于确保跨表,数据库和分布式系统的独特性。
句法:
-- Create a table with GUID as the primary key
CREATE TABLE table_name (
column_name RAW(16) DEFAULT SYS_GUID() PRIMARY KEY,
other_column_name column_type(size),
...
);
-- Insert the data into the table
INSERT INTO table_name (column2, column3, ...) VALUES (value2, value3, ...);
-- To display the data
SELECT RAWTOHEX(column_name), other_column_name FROM table_name;
例子:
-- Create a table
CREATE TABLE Employees (
Employee_id RAW(16) DEFAULT SYS_GUID() PRIMARY KEY,
Employee_dept NVARCHAR2(50),
Salary DECIMAL(10,2)
);
--Insert the values
INSERT INTO Employees (Employee_dept, Salary) VALUES ('HR', 50000.00);
INSERT INTO Employees (Employee_dept, Salary) VALUES ('Finance', 60000.50);
INSERT INTO Employees (Employee_dept, Salary) VALUES ('IT', 75000.75);
--To display the data
SELECT RAWTOHEX(Employee_id) AS Employee_ID, Employee_dept, Salary FROM Employees;
输出:

解释: 每行自动获得一个唯一的指导,称为雇员_id。由于Employee_id被存储为RAW(16),因此我们使用RawTohex(雇员_ID)将其转换为可读格式。
方法6:直接在Oracle SQL上使用插入语句的序列
Oracle SQL中的序列是用于生成唯一数字值的数据库对象,通常用于主键
句法:
--We create a separate sequence and use it manually in the INSERT Statements
CREATE SEQUENCE sequence_name
START WITH initial_value
INCREMENT BY step_value
[optional parameters];
CREATE TABLE table_name (
column_name NUMBER PRIMARY KEY,
other_column_name column_type(size),
...
);
--Inserting data using SEQUENCE
INSERT INTO table_name (column1, column2, column3, ...)
VALUES (sequence_name.NEXTVAL, value2, value3, ...);
--To display the data
SELECT * FROM table_name;
例子:
--To create a separate sequence
CREATE SEQUENCE employee_seq
START WITH 1
INCREMENT BY 1
NOCYCLE NOCACHE;
CREATE TABLE Employees (
Employee_id NUMBER PRIMARY KEY,
Employee_dept NVARCHAR2(50),
Salary DECIMAL(10,2)
);
--Insert into the table
INSERT INTO Employees (Employee_id, Employee_dept, Salary)
VALUES (employee_seq.NEXTVAL, 'HR', 50000.00);
INSERT INTO Employees (Employee_id, Employee_dept, Salary)
VALUES (employee_seq.NEXTVAL, 'Finance', 60000.50);
INSERT INTO Employees (Employee_id, Employee_dept, Salary)
VALUES (employee_seq.NEXTVAL, 'IT', 75000.75);
--To display the table
SELECT * FROM Employees;
输出:

解释: Employee_seq生成唯一的数字ID。员工_ID未自动生成,因此我们可以使用序列手动分配值。
方法7:在Oracle SQL上使用序列和GUID的组合
此方法将基于数字序列的ID与GUID结合在一起,以确保局部索引效率和全局唯一性。
句法:
--Create a sequence
CREATE SEQUENCE sequence_name
START WITH initial_value
INCREMENT BY step_value
[optional parameters];
CREATE TABLE table_name (
column1 NUMBER DEFAULT sequence_name.NEXTVAL PRIMARY KEY,
column2 RAW(16) DEFAULT SYS_GUID(),
column3 column_type(size),
...
);
--Insert the data into a table
INSERT INTO table_name (column3, column4, ...)
VALUES (value3, value4, ...);
--To display the table
SELECT column1, RAWTOHEX(column2), column3 FROM table_name;
例子:
--Create an Employee table with SEQUENCE and GUID
CREATE SEQUENCE employee_seq
START WITH 1
INCREMENT BY 1
NOCYCLE NOCACHE;
CREATE TABLE Employees (
Employee_id NUMBER DEFAULT employee_seq.NEXTVAL PRIMARY KEY,
Employee_uuid RAW(16) DEFAULT SYS_GUID(),
Employee_dept NVARCHAR2(50),
Salary DECIMAL(10,2)
);
--Inserting data into a table
INSERT INTO Employees (Employee_dept, Salary) VALUES ('HR', 50000.00);
INSERT INTO Employees (Employee_dept, Salary) VALUES ('Finance', 60000.50);
INSERT INTO Employees (Employee_dept, Salary) VALUES ('IT', 75000.75);
--Display data from the employee table
SELECT RAWTOHEX(Employee_uuid) AS Employee_UUID, Salary FROM Employees;
输出:

解释: 数字ID的序列(Employee_ID)。全球唯一值的GUID(RAW(16))列
方法8:使用Oracle SQL上的自定义逻辑的插入之前插入触发器
此方法使用a之前的插入触发器来根据最大现有雇员_id(MAX(雇员_ID))自动分配员工_ID和从序列(雇员_seq.nextval)的下一个值。
句法:
CREATE SEQUENCE sequence_name
START WITH initial_value
INCREMENT BY step_value
[optional parameters];
CREATE TABLE table_name (
column1 NUMBER PRIMARY KEY,
column2 column_type(size),
...
);
--Create BEFORE INSERT TRIGGER
CREATE OR REPLACE TRIGGER trigger_name
BEFORE INSERT ON table_name
FOR EACH ROW
BEGIN
IF :NEW.column1 IS NULL THEN
SELECT COALESCE(MAX(column1), sequence_name.NEXTVAL) + 1
INTO :NEW.column1
FROM table_name;
END IF;
END;
/
--Insert the data
INSERT INTO table_name (column2, column3, ...)
VALUES (value2, value3, ...);
--Display the table
SELECT * FROM table_name;
例子:
-- Step 1: Create a Sequence for Employee ID
CREATE SEQUENCE employee_seq
START WITH 1
INCREMENT BY 1
NOCYCLE NOCACHE;
-- Step 2: Create the Employees Table
CREATE TABLE Employees (
Employee_id NUMBER PRIMARY KEY,
Employee_dept NVARCHAR2(50),
Salary DECIMAL(10,2)
);
-- Step 3: Create a BEFORE INSERT Trigger for Auto-Increment
CREATE OR REPLACE TRIGGER employees_before_insert
BEFORE INSERT ON Employees
FOR EACH ROW
DECLARE
v_max_id NUMBER;
BEGIN
-- Check the max Employee_id in case the sequence is behind
SELECT COALESCE(MAX(Employee_id), 0) INTO v_max_id FROM Employees;
-- Assign the next ID (greater of max ID or sequence nextval)
:NEW.Employee_id := GREATEST(v_max_id + 1, employee_seq.NEXTVAL);
END;
/
-- Step 4: Insert Data (Trigger will auto-generate Employee_id)
INSERT INTO Employees (Employee_dept, Salary) VALUES ('HR', 50000.00);
INSERT INTO Employees (Employee_dept, Salary) VALUES ('Finance', 60000.50);
INSERT INTO Employees (Employee_dept, Salary) VALUES ('IT', 75000.75);
-- Step 5: Display Data
SELECT * FROM Employees;
输出:

解释: 序列用于生成数字ID。 a之前的插入触发器设置了员工_id
Oracle SQL上自动插入方法的性能比较
方法 | 用例 | 优点 | 缺点 |
身份列 | 当需要简单的自动插入时 | 无需触发器或序列 | 如果交易回滚,可能会发生差距。但是,使用nocache最大程度地减少了间隙,并增加1 |
序列和触发器 | 适合遗产系统 | 可以处理手动ID替代 | 由于额外的PL/SQL执行,性能开销 |
默认的序列 | 最适合Oracle 12c+而无需触发器 | 身份列之后的最佳性能 | 需要手动处理间隙 |
在使用Max(ID)插入触发器之前 | 对于避免ID差距很重要的小桌子有用 | 防止序列间隙 | 可能在高并发状态下引起锁定问题 |
GUID | 最适合分布式数据库 | 确保跨多个数据库的独特性 | 消耗更多的存储空间 |
直接使用插入语句的序列 | 最好的时候需要序列,但没有自动灌溉执行 | 不需要触发器 | 需要在每个插件中明确使用 |
序列 + GUID | 最适合混合环境 | 防止ID碰撞分布式系统中 | 需要额外的存储空间 |
在使用自定义逻辑插入触发器之前 | 对于高级用例,需要复杂的ID。 | 可以实施自定义规则 | 自定义逻辑可以减慢插入片段 |
现实世界的例子
1。电子商务系统: 在电子商务系统中,我们需要创建一个客户表,每个客户都会自动获得唯一的ID。
例子:
-- Create a sequence
CREATE SEQUENCE customer_seq START WITH 1 INCREMENT BY 1;
-- Create the Customers table
CREATE TABLE CUSTOMERS (
CUSTOMER_ID NUMBER PRIMARY KEY,
NAME VARCHAR2(100),
EMAIL VARCHAR2(100) UNIQUE
);
-- Create a trigger to auto-increment CUSTOMER_ID
CREATE OR REPLACE TRIGGER customer_trigger
BEFORE INSERT ON CUSTOMERS
FOR EACH ROW
BEGIN
SELECT customer_seq.NEXTVAL INTO :NEW.CUSTOMER_ID FROM DUAL;
END;
/
INSERT INTO CUSTOMERS (NAME, EMAIL) VALUES ('Alice Johnson', '[email protected]');
INSERT INTO CUSTOMERS (NAME, EMAIL) VALUES ('Bob Smith', '[email protected]');
COMMIT;
--To display the table
SELECT CUSTOMER_ID,name FROM CUSTOMERS;
输出:

解释: Customer_Seq是一个以1开始的序列,每行增加1个。该序列将用于自动生成唯一的Customer_ID值。
2。人力资源系统: 在人力资源系统中,我们需要为员工存储自动向员工ID存储。
例子:
CREATE TABLE EMPLOYEES (
EMPLOYEE_ID NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
FULL_NAME VARCHAR2(100),
SALARY NUMBER(10,2)
);
--Insert some values into it
INSERT INTO EMPLOYEES (FULL_NAME, SALARY) VALUES ('John Doe', 50000);
INSERT INTO EMPLOYEES (FULL_NAME, SALARY) VALUES ('Jane Smith', 60000);
COMMIT;
--To display the table
SELECT EMPLOYEE_ID,salary FROM EMPLOYEES;
输出 :

解释: 生成的始终作为身份声明使员工_ID自动插入类似于MySQL中的自动插入。 Oracle SQL自动为列生成唯一的顺序数字。
3。销售系统: 在销售系统中,我们使用自动生成的订单_id跟踪订单
例子:
-- Create a sequence
CREATE SEQUENCE order_seq START WITH 1000 INCREMENT BY 1;
-- Create the Orders table
CREATE TABLE ORDERS (
ORDER_ID NUMBER PRIMARY KEY,
CUSTOMER_NAME VARCHAR2(100),
ORDER_DATE DATE DEFAULT SYSDATE
);
-- Create a trigger to auto-increment ORDER_ID
CREATE OR REPLACE TRIGGER order_trigger
BEFORE INSERT ON ORDERS
FOR EACH ROW
BEGIN
SELECT order_seq.NEXTVAL INTO :NEW.ORDER_ID FROM DUAL;
END;
/
--Insert some data into the table
INSERT INTO ORDERS (CUSTOMER_NAME) VALUES ('Charlie Brown');
INSERT INTO ORDERS (CUSTOMER_NAME) VALUES ('Lucy Van Pelt');
COMMIT;
--To display the table
SELECT ORDER_ID,ORDER_DATE FROM ORDERS;
输出:

解释: sequence Order_seq:创建一个名为order_seq的序列,该序列将生成唯一的数字。每次使用序列时,下一个数字都会增加1。
结论
您可以使用序列,身份列,GUID等在Oracle上使用Auto_increment创建ID,这些方法会根据给定的条件自动增加ID。根据性能比较表中提到的要求和用例选择该方法。了解这些方法可帮助您有效地自动化Oracle上的ID列。
常见问题解答
1。甲骨文是否像mysql一样支持自动increment?
不,Oracle使用序列和触发器而不是自动插入来生成唯一的ID。
2。如何在Oracle中创建自动报重ID?
您可以创建一个序列,并在插入语句或插入触发器之前使用它。
3。我可以在Oracle中使用无触发的序列吗?
是的,您可以直接从插入到语句中的序列中直接使用NextVal。
4。如何重置Oracle序列?
您需要删除并重新创建序列或使用具有新的Qualit的“ Alter sequence”。
5。可以通过多个表共享oracle序列吗?
是的,序列独立于表,如果需要,可以用于多个表。