作者: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_id101 的员工薪水增加 10%:

UPDATE employees
SET salary = salary * 1.10
WHERE employee_id = 101;

修改 employee_id103 的员工的 first_namesalary

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_id105 的员工记录:

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 子句在 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 语句,明确指定了所有列名和对应的值。
  1. 插入部分列到 products
INSERT INTO products (product_id, product_name, category)
VALUES (2, 'Basic Mouse', 'Accessories');
  • 解析: 只为指定的列提供了值。未指定的 pricestock_quantity 列将根据表定义获得默认值或 NULL
  1. 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 表的列对应插入。
  1. 更新特定产品信息:
UPDATE products
SET price = 1150.00,stock_quantity = stock_quantity - 5
WHERE product_id = 1;
  • 解析: 使用 UPDATE 语句,SET 子句指定了要修改的多个列及其新值。WHERE 子句精确定位到 product_id 为 1 的记录。
  1. 批量更新产品价格:
UPDATE products
SET price = price * 1.10
WHERE category = 'Accessories';
  • 解析: WHERE 子句筛选出所有类别为 ‘Accessories’ 的产品,然后它们的 price 被更新为原价格的1.1倍。
  1. 删除库存为0的产品:
DELETE FROM products
WHERE stock_quantity = 0;
  • 解析: DELETE 语句通过 WHERE 子句找到所有 stock_quantity 为 0 的记录并删除它们。
  1. 插入新订单到 orders
INSERT INTO orders (order_id, product_id, customer_name, order_date, quantity_ordered)
VALUES (1001, 1, 'John Smith', SYSDATE, 2);
  • 解析: 插入新的订单记录。SYSDATE 是 Oracle 获取当前系统日期和时间的函数。
  1. 更新特定订单数量:
UPDATE orders
SET quantity_ordered = 3
WHERE order_id = 1001;
  • 解析: UPDATE 语句根据 order_id 定位到特定订单,并修改其 quantity_ordered
  1. 删除特定产品的所有订单:
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)。
  1. 清空 orders 表数据:
DELETE FROM orders;
  • 解析: 由于没有 WHERE 子句,此 DELETE 语句将删除 orders 表中的所有行。表结构会保留。
  • 更高效的替代方案 (不可回滚,但更快,且是DDL操作): TRUNCATE TABLE orders;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/909825.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/909825.shtml
英文地址,请注明出处:http://en.pswp.cn/news/909825.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

推荐使用的Unity插件(InputSystem)

本文将提供更简洁的步骤和常见问题解决。 一、极简入门步骤&#xff1a; 安装&#xff1a;Package Manager中安装Input System&#xff08;确保Unity版本在2019.4&#xff09; 创建Input Actions&#xff1a; 在Project窗口右键 -> Create -> Input Actions 双击打开…

清理 Docker 容器日志文件方法

操作总结与问题解析 一、操作目的与背景 用户旨在清理 Docker 容器日志文件以释放服务器存储空间,主要通过以下命令组合完成操作: 查看容器日志空间占用清空指定容器的日志文件验证容器运行状态与日志清理效果二、关键命令与输出解析 1. 查看 Docker 容器日志空间占用 du…

图片压缩工具 | 按指定高度垂直切割图片

OPEN-IMAGE-TINY&#xff0c;一个基于 Electron VUE3 的图片压缩工具&#xff0c;项目开源地址&#xff1a;https://github.com/0604hx/open-image-tiny ℹ️ 需求描述 在上一篇文章一段代码利用 snapdom 将 CSDN 博文转化为长图片&#xff08;PNG/JPG/PDF&#xff09;中&…

山东大学软件学院创新项目实训开发日志——第十七周(二)

目录 1.优化前端日历页面显示&#xff0c;增加鼠标悬停显示当日会议基本信息的效果。 2.优化会议计划生成与会议PPT生成功能&#xff0c;使得能够加载多页docx文件与PDF文件 3.优化了会议PPT生成功能&#xff0c;使得可以上传多个文件并根据多个文件生成会议PPT 4.修改了识…

Ubuntu 使用kubeadm部署k8s系统组件反复重启的问题

系统&#xff1a;Ubuntu 24.04 LTS 问题现象&#xff1a;kubeadm init 后系统组件proxy、apiserver、etcd等频繁挂掉重启 问题原因&#xff1a;cgroup配置问题 解决方法&#xff1a; 编辑系统cgroup默认配置文件 sudo nano /etc/default/grub 将GRUB_CMDLINE_LINUX_DEFAU…

Oracle获取执行计划之EXPLAIN PLAN 技术详解

#Oracle #执行计划 #EXPLAIN PLAN 一、引言 在Oracle数据库性能优化中&#xff0c;​执行计划&#xff08;Execution Plan&#xff09;​是理解SQL语句如何被数据库处理的关键工具。EXPLAIN PLAN是Oracle提供的一种静态分析SQL执行路径的方法&#xff0c;它通过生成逻辑执行…

【论文阅读】Qwen2.5-VL Technical Report

Arxiv:https://arxiv.org/abs/2502.13923 Source code:https://github.com/QwenLM/Qwen2.5-VL Author’s Institution&#xff1a;Alibaba 背景 多模态大模型 多模态大模型MultiModal Large Language Models (MM-LLMs) 的发展可以通过一篇综述了解&#xff1a;MM-LLMs: Re…

vue中computed和watch区别

在 Vue 中&#xff0c;computed 和 watch 都是用来响应式地处理数据变化的工具&#xff0c;但它们的用途和行为有明显区别。 &#x1f50d; 一句话总结 computed&#xff1a;用于声明式计算属性&#xff0c;有缓存。 watch&#xff1a;用于监听响应式数据的变化并执行副作用逻…

大语言模型:提示词决定自我反思效果: “检查回答是否错误” “验证回答是否正确”

大语言模型(LLMs)自我反思的结果很容易受提示词构造的影响 大型语言模型(LLMs)展现出令人印象深刻的零样本和少样本推理能力。有人提出,这些能力可以通过自我反思来提升,即让大型语言模型反思自己的输出,以识别和纠正初始回答中的错误。然而,尽管有一些证据表明自我反…

【iReport】实际开发中,解决iReport中打印图片不显示问题

ireport 中增加图片&#xff0c;添加上属性&#xff0c;但是运行时报错如下&#xff0c;是属性logoPath没有声明到map中 1. Parameter not found : logoPath net.sf.jasperreports.engine.design.JRValidationException: Report design not valid : 1. Parameter not fo…

【MySQL进阶】常用MySQL程序

目录 一. mysqlcheck——表维护程序 1.1.作用 1.2 注意事项 1.3 使用方法 1.4 常用选项 1.5 mysqlcheck的特殊使用 二. mysqldump——数据库备份程序 2.1.作用 2.2 注意事项 2.3 使用方法 2.4 常用选项 三. mysqladmin——MySQL 服务器管理程序 3.1.作用 3.2 使用…

EMQX高效存储消息到MySQL指南

配置 EMQX 存储消息到 MySQL EMQX 可以通过规则引擎和数据桥接功能将消息和事件存储到 MySQL 数据库。以下是具体实现方法&#xff1a; 创建 MySQL 数据表 在 MySQL 中创建用于存储消息的表结构&#xff1a; CREATE TABLE mqtt_messages (id int(11) NOT NULL AUTO_INCREME…

springboot项目,利用docker打包部署

Windows WSL2 Docker Desktop 部署 SpringBoot 项目指南 &#xff08;没有安装docker的&#xff0c;如果是windows家庭中文版的&#xff0c;可以看我上一篇帖子&#xff1a;windows家庭版安装docker和redis-CSDN博客&#xff09; 本教程将说明如何在 Windows 系统 下&#…

MO+内核32位普冉单片机PY32F003开发板

PY32F003开发板是基于普冉半导体PY32F003微控制器设计的低成本入门级开发工具&#xff0c; PY32F003系列微控制器采用高性能的 32 位ARM Cortex-M0内核&#xff0c;宽电压工作范围的 MCU。嵌入高达32Kbytes flash 和 4Kbytes SRAM 存储器&#xff0c;最高工作频率 32MHz。PY32…

MySql 用存储过程删除所有用户表

用拼接语句总是会出问题 -- 1. 禁用外键约束&#xff08;防止级联删除失败&#xff09;[1]() SET SESSION FOREIGN_KEY_CHECKS 0; -- 2. 生成并执行删除语句&#xff08;替换 your_database_name&#xff09; SELECT CONCAT(DROP TABLE IF EXISTS , TABLE_NAME, ;) -- 预览语…

Java八股文——MySQL「锁篇」

讲一下MySQL里有哪些锁&#xff1f; 面试官您好&#xff0c;MySQL中的锁机制非常丰富&#xff0c;它是保证数据一致性和并发安全的核心。我通常会从锁的粒度&#xff08;加锁范围&#xff09; 和锁的模式&#xff08;功能&#xff09; 这两个维度来理解它们。 第一维度&#…

B站精品课程

【Python并发编程】线程&#xff0c;进程&#xff0c;协程&#xff0c;线程安全&#xff0c;多线程&#xff0c;死锁&#xff0c;线程池等与案例解析&#xff0c;从入门到精通 https://www.bilibili.com/video/BV1EfdcYmEff/?spm_id_from333.337.search-card.all.click&v…

# ubuntu中安装使用五笔输入法

先 清理旧输入法并重新安装 fcitx5 五笔输入法&#x1f447; &#x1f4e6; 第一步&#xff1a;清理旧的 Fcitx5 及相关输入法组件 sudo apt purge fcitx* mozc* ibus* -y sudo apt autoremove --purge -y&#x1f4dd; 说明&#xff1a; fcitx* 会清除旧版本 Fcitx/Fcitx5。…

LSM树与B+树优缺点分析

1. LSM树优化了顺序写&#xff0c;因此写性能很好&#xff0c;但在查询上&#xff1a; 需要从Level 0到Level n一直顺序查下去。极端情况是LSM树中不存在该数据&#xff0c;则需要遍历L0->Ln&#xff0c;最后返回空集。 解决方法是用布隆过滤器优化查询。 2. B树范围查询性…

【成都鱼住未来身份证】 身份证读取与解析———未来之窗行业应用跨平台架构——智能编程——仙盟创梦IDE

读取身份证开发配置 function readerid鱼住未来科技(){const webUrl http:// "127.0.0.1:30004" /api/info$.ajax({url: webUrl,type: GET,dataType: json,success: function (result) {// processContent.text(web api接口&#xff1a; webUrl 读取身份证信息…