作者:IvanCodes
日期:2025年6月18日
專欄:Oracle教程
在 Oracle 數據庫中,對表內數據進行增加、修改和刪除操作是通過數據操作語言 (DML - Data Manipulation Language) 來完成的。核心的DML語句包括 INSERT
(插入新數據), UPDATE
(修改現有數據), 和 DELETE
(刪除數據)。掌握這些語句是數據庫開發和管理的基礎。
思維導圖
一、插入數據 (INSERT)
INSERT
語句用于向表中添加新的行記錄。
1.1 插入單行數據,指定所有列的值
語法:
INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);
table_name
: 要插入數據的表名。(column1, column2, ...)
: 可選。指定要插入數據的列名列表。如果省略此列表,則VALUES
子句中必須提供表中所有列的值,并且順序必須與表中列的定義順序完全一致。VALUES (value1, value2, ...)
: 提供要插入的具體值。值的順序和類型必須與列名列表 (或表定義中的列順序) 匹配。
代碼案例:
假設有一個 employees
表:
CREATE TABLE employees (employee_id NUMBER(6) PRIMARY KEY,first_name VARCHAR2(20),last_name VARCHAR2(25) NOT NULL,email VARCHAR2(25) NOT NULL UNIQUE,hire_date DATE DEFAULT SYSDATE,salary NUMBER(8,2)
);
插入一條完整的員工記錄:
INSERT INTO employees (employee_id, first_name, last_name, email, hire_date, salary)
VALUES (101, 'John', 'Doe', 'john.doe@example.com', TO_DATE('2023-01-15', 'YYYY-MM-DD'), 60000);
如果省略列名列表 (不推薦,除非非常清楚表結構且列順序不會改變):
INSERT INTO employees
VALUES (102, 'Jane', 'Smith', 'jane.smith@example.com', TO_DATE('2023-02-20', 'YYYY-MM-DD'), 75000);
1.2 插入單行數據,指定部分列的值
如果某些列允許為 NULL
或有 DEFAULT
值,你可以只插入部分列的數據。
語法:
INSERT INTO table_name (column_a, column_b)
VALUES (value_a, value_b);
代碼案例:
插入一個員工,只提供必要信息,hire_date
使用默認值,salary
暫時不指定 (將為 NULL):
INSERT INTO employees (employee_id, first_name, last_name, email)
VALUES (103, 'Peter', 'Jones', 'peter.jones@example.com');
1.3 插入多行數據 (INSERT ALL)
Oracle 提供了 INSERT ALL
語句,可以一次性向一個或多個表中插入多行數據。
語法 (插入到同一張表的多行):
INSERT ALLINTO table_name (column1, column2, ...) VALUES (value1_row1, value2_row1, ...)INTO table_name (column1, column2, ...) VALUES (value1_row2, value2_row2, ...)...
SELECT * FROM dual; -- dual是Oracle的虛擬表,這里用于觸發INSERT ALL
代碼案例:
INSERT ALLINTO employees (employee_id, first_name, last_name, email, salary) VALUES (104, 'Alice', 'Wonder', 'alice.w@example.com', 55000)INTO employees (employee_id, first_name, last_name, email, salary) VALUES (105, 'Bob', 'Marley', 'bob.m@example.com', 62000)
SELECT * FROM dual;
1.4 從其他表插入數據 (INSERT INTO … SELECT)
可以將一個 SELECT
語句的查詢結果直接插入到另一個表中。
語法:
INSERT INTO target_table (column1, column2, ...)
SELECT source_column1, source_column2, ...
FROM source_table
WHERE condition;
代碼案例:
假設有一個 employees_archive
表,結構與 employees
類似。將 employees
表中薪水低于50000的員工備份到 employees_archive
:
INSERT INTO employees_archive (employee_id, first_name, last_name, email, hire_date, salary)
SELECT employee_id, first_name, last_name, email, hire_date, salary
FROM employees
WHERE salary < 50000;
二、修改數據 (UPDATE)
UPDATE
語句用于修改表中已存在行的列值。
2.1 修改特定行的列值
語法:
UPDATE table_name
SET column1 = value1,column2 = value2,...
WHERE condition;
table_name
: 要更新的表名。SET column1 = value1, ...
: 指定要修改的列及其新值。WHERE condition
: 非常重要!指定哪些行需要被更新。如果省略WHERE
子句,表中所有行的指定列都會被更新,這通常是危險操作。
代碼案例:
將 employee_id
為 101
的員工薪水增加 10%:
UPDATE employees
SET salary = salary * 1.10
WHERE employee_id = 101;
修改 employee_id
為 103
的員工的 first_name
和 salary
:
UPDATE employees
SET first_name = 'Pete',salary = 52000
WHERE employee_id = 103;
2.2 修改所有行的列值 (謹慎使用)
代碼案例:
給所有員工的薪水普調增加500 (假設所有員工都適用):
UPDATE employees
SET salary = salary + 500;
-- 再次強調:沒有WHERE子句會更新所有行,操作前務必確認!
2.3 使用子查詢更新數據
SET
子句中的值或 WHERE
子句中的條件可以來源于子查詢。
代碼案例:
假設有一個 departments_avg_salary
表 (department_id, avg_sal)。將 employees
表中每個員工的薪水更新為其所在部門的平均薪水 (僅為示例,實際邏輯可能更復雜)。
-- 僅為語法示例,實際邏輯可能需要更復雜的關聯更新
UPDATE employees e
SET e.salary = (SELECT d.avg_salFROM departments_avg_salary dWHERE e.department_id = d.department_id) -- 假設employees表有department_id
WHERE EXISTS (SELECT 1FROM departments_avg_salary dWHERE e.department_id = d.department_id);
更常見的做法是使用 Oracle 的 MERGE
語句進行復雜的關聯更新。
三、刪除數據 (DELETE)
DELETE
語句用于從表中刪除一行或多行記錄。
3.1 刪除特定行
語法:
DELETE FROM table_name
WHERE condition;
table_name
: 要刪除數據的表名。WHERE condition
: 非常重要!指定哪些行需要被刪除。如果省略WHERE
子句,表中所有行都會被刪除 (效果類似TRUNCATE TABLE
,但DELETE
可以回滾,TRUNCATE
通常不行且更快,不過TRUNCATE
不是本節重點)。
代碼案例:
刪除 employee_id
為 105
的員工記錄:
DELETE FROM employees
WHERE employee_id = 105;
刪除所有薪水低于40000的員工:
DELETE FROM employees
WHERE salary < 40000;
3.2 刪除所有行 (謹慎使用)
代碼案例:
DELETE FROM employees;
-- 這會刪除employees表中的所有數據,但表結構依然存在。
-- 如果要快速清空表并且不需要DML的回滾能力,TRUNCATE TABLE employees; 效率更高。
重要提示: 所有的 INSERT
, UPDATE
, DELETE
操作在默認情況下(取決于您的客戶端工具設置,如SQL*Plus或SQL Developer)不是自動提交的。您需要顯式使用 COMMIT
命令來永久保存更改,或者使用 ROLLBACK
命令來撤銷未提交的更改。如果不提交就關閉會話,未提交的更改通常會自動回滾。
總結: INSERT
, UPDATE
, DELETE
是日常數據庫操作的核心。務必理解它們的語法,特別是 WHERE
子句在 UPDATE
和 DELETE
中的重要性,以避免意外修改或刪除數據。
練習題
背景表結構:
假設我們有以下兩個表:
create table products (
product_id NUMBER PRIMARY KEY,
product_name VARCHAR2(100),
category VARCHAR2(50),
price NUMBER(8,2),
stock_quantity NUMBER);
create table orders (
order_id NUMBER PRIMARY KEY,
product_id NUMBER,
customer_name VARCHAR2(100),
order_date DATE,
quantity_ordered NUMBER,
FOREIGN KEY (product_id) REFERENCES products(product_id));
請為以下每個場景編寫相應的SQL DML語句。 (提交您的DML語句后,記得使用 COMMIT;
保存更改,或 ROLLBACK;
撤銷操作,除非題目特別說明不需要。)
題目:
- 向
products
表中插入一條新產品記錄:product_id=1, product_name=‘Super Laptop’, category=‘Electronics’, price=1200.50, stock_quantity=50。 - 向
products
表中插入一條新產品記錄,只提供 product_id=2, product_name=‘Basic Mouse’, category=‘Accessories’。假設 price 和 stock_quantity 允許為空或有默認值。 - 創建一個名為
special_offers
的新表,其結構包含 product_id, product_name, offer_price。然后從products
表中選擇所有category
為 ‘Electronics’ 且price
大于1000的產品,將其product_id
,product_name
以及price * 0.9
(作為 offer_price) 插入到special_offers
表中。(只需寫INSERT INTO…SELECT部分,假設special_offers表已創建)。 - 將
products
表中product_id
為 1 的產品的price
更新為 1150.00,并將stock_quantity
減少 5。 - 將
products
表中所有category
為 ‘Accessories’ 的產品的price
提高10%。 - 刪除
products
表中stock_quantity
為 0 的所有產品記錄。 - 向
orders
表中插入一條新的訂單記錄:order_id=1001, product_id=1, customer_name=‘John Smith’, order_date=當前系統日期, quantity_ordered=2。 - 更新
orders
表中order_id
為 1001 的訂單,將其quantity_ordered
修改為 3。 - 假設由于產品
product_id
=2 已停產,需要刪除orders
表中所有與該產品相關的訂單記錄。 - 清空
orders
表中的所有數據,但保留表結構。
答案與解析:
- 插入新產品到
products
:
INSERT INTO products (product_id, product_name, category, price, stock_quantity)
VALUES (1, 'Super Laptop', 'Electronics', 1200.50, 50);
- 解析: 使用了標準的
INSERT INTO ... VALUES
語句,明確指定了所有列名和對應的值。
- 插入部分列到
products
:
INSERT INTO products (product_id, product_name, category)
VALUES (2, 'Basic Mouse', 'Accessories');
- 解析: 只為指定的列提供了值。未指定的
price
和stock_quantity
列將根據表定義獲得默認值或NULL
。
- 從
products
插入到special_offers
:
(假設special_offers
表已創建,結構:product_id NUMBER, product_name VARCHAR2(100), offer_price NUMBER(8,2))
INSERT INTO special_offers (product_id, product_name, offer_price)
SELECT product_id, product_name, price * 0.9
FROM products
WHERE category = 'Electronics' AND price > 1000;
- 解析: 使用
INSERT INTO ... SELECT
結構。SELECT
語句從products
表篩選數據,并計算offer_price
。查詢結果的列與special_offers
表的列對應插入。
- 更新特定產品信息:
UPDATE products
SET price = 1150.00,stock_quantity = stock_quantity - 5
WHERE product_id = 1;
- 解析: 使用
UPDATE
語句,SET
子句指定了要修改的多個列及其新值。WHERE
子句精確定位到product_id
為 1 的記錄。
- 批量更新產品價格:
UPDATE products
SET price = price * 1.10
WHERE category = 'Accessories';
- 解析:
WHERE
子句篩選出所有類別為 ‘Accessories’ 的產品,然后它們的price
被更新為原價格的1.1倍。
- 刪除庫存為0的產品:
DELETE FROM products
WHERE stock_quantity = 0;
- 解析:
DELETE
語句通過WHERE
子句找到所有stock_quantity
為 0 的記錄并刪除它們。
- 插入新訂單到
orders
:
INSERT INTO orders (order_id, product_id, customer_name, order_date, quantity_ordered)
VALUES (1001, 1, 'John Smith', SYSDATE, 2);
- 解析: 插入新的訂單記錄。
SYSDATE
是 Oracle 獲取當前系統日期和時間的函數。
- 更新特定訂單數量:
UPDATE orders
SET quantity_ordered = 3
WHERE order_id = 1001;
- 解析:
UPDATE
語句根據order_id
定位到特定訂單,并修改其quantity_ordered
。
- 刪除特定產品的所有訂單:
DELETE FROM orders
WHERE product_id = 2;
- 解析:
DELETE
語句刪除orders
表中所有product_id
為 2 的訂單。由于orders.product_id
有外鍵約束引用products.product_id
,如果products
表中product_id
=2 的記錄也需要刪除,通常需要先刪除orders
中的相關記錄 (或者外鍵設置了級聯刪除ON DELETE CASCADE
)。
- 清空
orders
表數據:
DELETE FROM orders;
- 解析: 由于沒有
WHERE
子句,此DELETE
語句將刪除orders
表中的所有行。表結構會保留。 - 更高效的替代方案 (不可回滾,但更快,且是DDL操作):
TRUNCATE TABLE orders;