Oracle 数据库数据操作:精通 INSERT, UPDATE, DELETE

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS AI 助手,专业版
简介: 在Oracle里,增加数据用INSERT,修改用UPDATE,删除则用DELETE。进行修改和删除时,建议总是带上WHERE条件来指定范围,这样可以确保操作的准确性

在 Oracle 数据库中,对表内数据进行增加、修改和删除操作是通过数据操作语言 (DML - Data Manipulation Language) 来完成的。核心的DML语句包括 INSERT (插入新数据), UPDATE (修改现有数据), 和 DELETE (删除数据)。掌握这些语句是数据库开发和管理基础

思维导图

image.png
image.png

一、插入数据 (INSERT)

INSERT 语句用于向表中添加新行记录

1.1 插入单行数据,指定所有列的值
语法:
sql INSERT INTO table_name (column1, column2, column3, ...) VALUES (value1, value2, value3, ...);
table_name: 要插入数据的表名。 (column1, column2, ...): 可选。指定要插入数据的列名列表。如果 省略此列表,则 VALUES 子句中 必须提供表中 所有列的值,并且 顺序必须与表中列的 定义顺序完全一致
VALUES (value1, value2, ...): 提供要插入的具体值。值的顺序和类型必须与列名列表 (或表定义中的列顺序) 匹配

代码案例:
假设有一个 employees 表:
sql 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) );
插入一条完整的员工记录:
sql 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);
如果省略列名列表 (不推荐,除非非常清楚表结构且列顺序不会改变):
sql INSERT INTO employees VALUES (102, 'Jane', 'Smith', 'jane.smith@example.com', TO_DATE('2023-02-20', 'YYYY-MM-DD'), 75000);

1.2 插入单行数据,指定部分列的值
如果某些列允许为 NULL 或有 DEFAULT 值,你可以只插入部分列的数据。

语法:
sql INSERT INTO table_name (column_a, column_b) VALUES (value_a, value_b);
代码案例:
插入一个员工,只提供必要信息,hire_date 使用默认值,salary 暂时不指定 (将为 NULL):
sql 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 语句,可以一次性一个或多个表中插入多行数据

语法 (插入到同一张表的多行):
```sql
INSERT ALL
INTO 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
<font color="darkgreen">**代码案例:**</font>sql
INSERT ALL
INTO 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;
<font color="darkred">**1.4 从其他表插入数据 (INSERT INTO ... SELECT)**</font> 可以将一个 `SELECT` 语句的<font color="olive">查询结果</font>直接插入到<font color="darkcyan">另一个表</font>中。 <font color="navy">**语法:**</font>sql
INSERT INTO target_table (column1, column2, ...)
SELECT source_column1, source_column2, ...
FROM source_table
WHERE condition;
<font color="saddlebrown">**代码案例:**</font> 假设有一个 `employees_archive` 表,结构与 `employees` 类似。将 `employees` 表中薪水低于50000的员工备份到 `employees_archive`:sql
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 修改特定行的列值
语法:
sql UPDATE table_name SET column1 = value1, column2 = value2, ... WHERE condition;
table_name: 要更新的表名。 SET column1 = value1, ...: 指定要 修改的列及其 新值
WHERE condition: 非常重要!指定哪些行需要被更新。如果省略 WHERE 子句,表中所有行的指定列都会被更新,这通常是危险操作

代码案例:
employee_id101 的员工薪水增加 10%:
```sql
UPDATE employees
SET salary = salary
1.10
WHERE employee_id = 101;
修改 `employee_id` 为 `103` 的员工的 `first_name` 和 `salary`:sql
UPDATE employees
SET first_name = 'Pete',
salary = 52000
WHERE employee_id = 103;
<font color="indigo">**2.2 修改所有行的列值 (谨慎使用)**</font> <font color="olive">**代码案例:**</font> 给所有员工的薪水普调增加500 (假设所有员工都适用):sql
UPDATE employees
SET salary = salary + 500;
-- 再次强调:没有WHERE子句会更新所有行,操作前务必确认!
<font color="indigo">**2.3 使用子查询更新数据**</font> `SET` 子句中的值或 `WHERE` 子句中的条件可以<font color="darkcyan">来源于子查询</font>。 <font color="saddlebrown">**代码案例:**</font> 假设有一个 `departments_avg_salary` 表 (department_id, avg_sal)。将 `employees` 表中每个员工的薪水更新为其所在部门的平均薪水 (仅为示例,实际逻辑可能更复杂)。sql
-- 仅为语法示例,实际逻辑可能需要更复杂的关联更新
UPDATE employees e
SET e.salary = (SELECT d.avg_sal
FROM departments_avg_salary d
WHERE e.department_id = d.department_id) -- 假设employees表有department_id
WHERE EXISTS (SELECT 1
FROM departments_avg_salary d
WHERE e.department_id = d.department_id);
`` 更常见的做法是使用 Oracle 的MERGE` 语句进行复杂的关联更新。

### 三、删除数据 (DELETE)

DELETE 语句用于从表中删除一行或多行记录

3.1 删除特定行
语法:
sql DELETE FROM table_name WHERE condition;
table_name: 要删除数据的表名。 WHERE condition: 非常重要!指定 哪些行需要被删除。如果 省略 WHERE 子句,表中 所有行都会被 删除 (效果类似 TRUNCATE TABLE,但 DELETE 可以回滚TRUNCATE 通常 不行且更快,不过 TRUNCATE 不是本节重点)。

代码案例:
删除 employee_id105 的员工记录:
sql DELETE FROM employees WHERE employee_id = 105;
删除所有薪水低于40000的员工:
sql DELETE FROM employees WHERE salary < 40000;

3.2 删除所有行 (谨慎使用)
代码案例:
sql DELETE FROM employees; -- 这会删除employees表中的所有数据,但表结构依然存在。 -- 如果要快速清空表并且不需要DML的回滚能力,TRUNCATE TABLE employees; 效率更高。
重要提示: 所有的 INSERT, UPDATE, DELETE 操作在 默认情况下(取决于您的客户端工具设置,如SQL Plus或SQL Developer)不是自动提交的。您需要显式使用 COMMIT 命令来永久保存更改,或者使用 ROLLBACK 命令来撤销未提交的更改。如果不提交就关闭会话,未提交的更改通常会自动回滚

总结: INSERT, UPDATE, DELETE日常数据库操作核心。务必理解它们的语法,特别是 WHERE 子句在 UPDATEDELETE 中的重要性,以避免意外修改或删除数据

---

### *练习题

背景表结构:
假设我们有以下两个表:

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; 撤销操作,除非题目特别说明不需要。)

题目:

  1. products 表中插入一条新产品记录:product_id=1, product_name='Super Laptop', category='Electronics', price=1200.50, stock_quantity=50。
  2. products 表中插入一条新产品记录,只提供 product_id=2, product_name='Basic Mouse', category='Accessories'。假设 price 和 stock_quantity 允许为空或有默认值。
  3. 创建一个名为 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表已创建)。
  4. products 表中 product_id 为 1 的产品的 price 更新为 1150.00,并将 stock_quantity 减少 5。
  5. products 表中所有 category 为 'Accessories' 的产品的 price 提高10%。
  6. 删除 products 表中 stock_quantity 为 0 的所有产品记录。
  7. orders 表中插入一条新的订单记录:order_id=1001, product_id=1, customer_name='John Smith', order_date=当前系统日期, quantity_ordered=2。
  8. 更新 orders 表中 order_id 为 1001 的订单,将其 quantity_ordered 修改为 3。
  9. 假设由于产品 product_id=2 已停产,需要删除 orders 表中所有与该产品相关的订单记录。
  10. 清空 orders 表中的所有数据,但保留表结构。
答案与解析:
  1. 插入新产品到 products

    INSERT INTO products (product_id, product_name, category, price, stock_quantity)
    VALUES (1, 'Super Laptop', 'Electronics', 1200.50, 50);
    
    • 解析: 使用了标准的 INSERT INTO ... VALUES 语句,明确指定了所有列名和对应的值。
  2. 插入部分列到 products

    INSERT INTO products (product_id, product_name, category)
    VALUES (2, 'Basic Mouse', 'Accessories');
    
    • 解析: 只为指定的列提供了值。未指定的 pricestock_quantity 列将根据表定义获得默认值或 NULL
  3. 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 表的列对应插入。
  4. 更新特定产品信息:

    UPDATE products
    SET price = 1150.00,
    stock_quantity = stock_quantity - 5
    WHERE product_id = 1;
    
    • 解析: 使用 UPDATE 语句,SET 子句指定了要修改的多个列及其新值。WHERE 子句精确定位到 product_id 为 1 的记录。
  5. 批量更新产品价格:

    UPDATE products
    SET price = price * 1.10
    WHERE category = 'Accessories';
    
    • 解析: WHERE 子句筛选出所有类别为 'Accessories' 的产品,然后它们的 price 被更新为原价格的1.1倍。
  6. 删除库存为0的产品:

    DELETE FROM products
    WHERE stock_quantity = 0;
    
    • 解析: DELETE 语句通过 WHERE 子句找到所有 stock_quantity 为 0 的记录并删除它们。
  7. 插入新订单到 orders

    INSERT INTO orders (order_id, product_id, customer_name, order_date, quantity_ordered)
    VALUES (1001, 1, 'John Smith', SYSDATE, 2);
    
    • 解析: 插入新的订单记录。SYSDATE 是 Oracle 获取当前系统日期和时间的函数。
  8. 更新特定订单数量:

    UPDATE orders
    SET quantity_ordered = 3
    WHERE order_id = 1001;
    
    • 解析: UPDATE 语句根据 order_id 定位到特定订单,并修改其 quantity_ordered
  9. 删除特定产品的所有订单:

    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)。
  10. 清空 orders 表数据:

    DELETE FROM orders;
    
    • 解析: 由于没有 WHERE 子句,此 DELETE 语句将删除 orders 表中的所有行。表结构会保留。
    • 更高效的替代方案 (不可回滚,但更快,且是DDL操作): TRUNCATE TABLE orders;
目录
相关文章
|
3月前
|
关系型数据库 MySQL 数据管理
MySQL数据库基本操作包括增加、删除、更新和查询
值得注意的是,虽然上述操作看起来直观易懂,但实际情况中可能会遇到数据类型、索引、性能优化和事务处理等高级话题。因此,数据库管理员或开发人员在对数据库进行操作时,应具备深入的理解和丰富的实践经验。
367 18
|
3月前
|
SQL 安全 关系型数据库
深入理解 MySQL 权限撤销(REVOKE)机制:从语法到安全实践
本文深入解析MySQL中REVOKE语句的语法、权限作用域、用户标识规范及安全实践,涵盖常见错误与最佳策略,助力精准撤销用户权限,提升数据库安全性与合规性。
153 14
|
7月前
|
SQL 关系型数据库 MySQL
MySQL group by 底层原理详解。group by 执行 慢 原因深度分析。(图解+秒懂+史上最全)
MySQL group by 底层原理详解。group by 执行 慢 原因深度分析。(图解+秒懂+史上最全)
MySQL group by 底层原理详解。group by 执行 慢 原因深度分析。(图解+秒懂+史上最全)
|
12月前
|
Web App开发 安全 Linux
【独家揭秘2025】VMware Workstation Pro虚拟机:免费安装教程大放送,一键解锁操作系统模拟神器!
VMware Workstation Pro 是由威睿(VMware)公司开发的一款功能强大的桌面虚拟化软件,允许用户在同一台物理计算机上同时运行多个操作系统,如Windows、..
1268 2
【独家揭秘2025】VMware Workstation Pro虚拟机:免费安装教程大放送,一键解锁操作系统模拟神器!
|
运维 网络协议 Linux
【专栏】 20 个 Linux 命令,运维工程师工作时最常用的
【4月更文挑战第28天】本文介绍了运维工程师常用的20个Linux命令,包括`ls`、`cd`、`pwd`、`mkdir`、`rm`、`cp`、`mv`、`cat`、`more`、`less`、`head`、`tail`、`grep`、`find`、`chmod`、`chown`、`chgrp`、`ps`、`top`和`ifconfig`,帮助提升工作效率。此外,还提到了其他常用的命令如`df`、`free`、`tar`、`ssh`、`scp`、`ping`、`netstat`、`iptables`、`systemctl`、`hostname`等,建议运维人员掌握以应对各种运维场景。
1581 1
|
网络协议 应用服务中间件 网络安全
小白必看:阿里云SSL证书免费申请流程,免费3个月到期解决方法
2024年阿里云提供免费SSL证书申请服务,品牌为Digicert,支持免费单域名证书,每个账号可申请20张,有效期3个月。用户需登录阿里云数字证书管理服务控制台,完成证书申请、域名绑定及DNS验证等步骤,操作简便快捷。更多详情见阿里云官网。
|
存储 负载均衡 NoSQL
一文让你搞懂 zookeeper
一文让你搞懂 zookeeper
19746 16
|
存储 关系型数据库 MySQL
Mysql全面总结
本文全面总结了MySQL的相关知识,涵盖思维导图、架构、存储引擎、数据类型、索引、查询、事务、锁机制、调优、分区与分表分库、主从复制及其他问题。MySQL采用插件式存储引擎架构,支持多种存储引擎,如InnoDB和MyISAM,每种引擎具备不同的特性。文章详细介绍了InnoDB和MyISAM的对比,包括事务支持、行级锁定、索引类型等。此外,还探讨了MySQL的查询优化、性能调优、主从复制等内容,适合数据库开发者和运维人员阅读。如涉及版权问题,请联系作者删除。
Mysql全面总结
|
关系型数据库 MySQL
Mysql 主键冲突(ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY')
Mysql 主键冲突(ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY')
2122 0