当前位置: 首页 > news >正文

SQL154 插入记录(一)

描述

牛客后台会记录每个用户的试卷作答记录到exam_record表,现在有两个用户的作答记录详情如下:

  • 用户1001在2021年9月1日晚上10点11分12秒开始作答试卷9001,并在50分钟后提交,得了90分;
  • 用户1002在2021年9月4日上午7点1分2秒开始作答试卷9002,并在10分钟后退出了平台。

试卷作答记录表exam_record中,表已建好,其结构如下,请用一条语句将这两条记录插入表中。

FiledTypeNullKeyExtraDefaultComment
idint(11)NOPRIauto_increment(NULL)自增ID
uidint(11)NO(NULL)用户ID
exam_idint(11)NO(NULL)试卷ID
start_timedatetimeNO(NULL)开始时间
submit_timedatetimeYES(NULL)提交时间
scoretinyint(4)YES(NULL)得分

该题最后会通过执行SELECT uid, exam_id, start_time, submit_time, score FROM exam_record;来对比结果

INSERT INTOexam_record (uid, exam_id, start_time, submit_time, score)
VALUES('1001','9001','2021-09-01 22:11:12','2021-09-01 23:01:12','90');
INSERT INTOexam_record (uid, exam_id, start_time)
VALUES('1002','9002','2021-09-04 07:01:02');

SQL INSERT INTO 语句:插入记录的不同方式

INSERT INTO 语句是 SQL 中用于向数据库表中添加新记录(行)的核心命令。根据需要插入的数据完整性、目标列的指定方式以及数据来源,有多种使用方式。

1. 完整插入 (指定所有列)
INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);
  • 说明: 明确指定要插入数据的所有列名(或大部分关键列),并在 VALUES 子句中提供对应顺序的值。
  • 优点: 清晰、安全、可读性强。即使表结构后续有变动(如新增列),只要新列有默认值或允许 NULL,此语句通常仍能正常执行。
  • 缺点: 需要写出所有列名,代码稍长。
  • 分析: 明确指定了 exam_record 表的 uidexam_idstart_timesubmit_timescore 这5个列,并提供了对应的值。这是一次完整的考试记录插入,包含了开始时间、提交时间和得分。
  • 示例
  • INSERT INTOexam_record (uid, exam_id, start_time, submit_time, score)
    VALUES('1001','9001','2021-09-01 22:11:12','2021-09-01 23:01:12','90');
2. 部分插入 (指定部分列)
INSERT INTO table_name (column1, column2, ...) -- 只列出需要赋值的列
VALUES (value1, value2, ...);
  • 说明: 只指定需要插入数据的部分列名。未指定的列将根据其定义被赋予默认值(如 DEFAULT 约束)、NULL(如果允许),或者如果该列是 AUTO_INCREMENT 主键,会自动生成下一个值。
  • 优点: 灵活,当某些列的值可以由数据库自动生成或可以为空时,无需手动指定。
  • 缺点: 需要清楚了解表结构和各列的约束(如 NOT NULL、默认值等),否则可能因缺少必要值而插入失败。
  • 分析: 只指定了 uidexam_idstart_time 三个列。submit_time 和 score 列未指定。
  • 结果: submit_time 很可能为 NULL(表示考试尚未提交),score 也为 NULL(或0,取决于表设计)。这通常用于记录用户开始考试的事件,最终成绩和提交时间将在考试结束后更新。
  • 示例
  • INSERT INTOexam_record (uid, exam_id, start_time)
    VALUES('1002','9002','2021-09-04 07:01:02');
3. 省略列名列表的插入 (不推荐)

语法:

INSERT INTO table_name
VALUES (value1, value2, value3, ...); -- 值的顺序必须严格匹配表的列顺序
  • 说明: 省略 () 中的列名列表。VALUES 中的值必须严格按照表定义的列顺序提供,且数量必须完全匹配。
  • 优点: 代码最短。
  • 缺点:
    • 极易出错: 一旦表结构改变(如增删列、调整列序),此语句极可能失败或插入到错误的列。
    • 可读性差: 无法直观看出每个值对应哪个列。
    • 灵活性差: 必须为所有列提供值,即使是 NULL 或默认值也需要显式写出来。
  • 结论: 强烈不推荐在生产环境或需要维护的代码中使用此方式。
4. 插入多行记录

语法:

INSERT INTO table_name (column1, column2, ...)
VALUES (value1a, value2a, ...),(value1b, value2b, ...),(value1c, value2c, ...);
  • 说明: 在一个 INSERT 语句中,通过 VALUES 后跟多组用逗号分隔的 (值) 来一次性插入多条记录。
  • 优点: 效率高,比执行多条单行 INSERT 语句更快,尤其是在处理大量数据时,减少了网络往返和事务开销。
  • 注意: 所有行的列名列表必须相同。
  • 示例:
    INSERT INTO exam_record (uid, exam_id, start_time)
    VALUES ('1003', '9001', '2021-09-05 10:00:00'),('1004', '9001', '2021-09-05 10:05:00'),('1005', '9003', '2021-09-06 14:30:00');
5. 从其他表插入数据 (INSERT INTO ... SELECT)

语法:

INSERT INTO table_name (column1, column2, ...)
SELECT column1, column2, ...
FROM source_table
WHERE condition;
  • 说明: 将一个 SELECT 查询的结果集直接插入到目标表中。
  • 优点: 强大且高效,适用于数据迁移、备份、根据条件复制数据等场景。
  • 注意: SELECT 查询返回的列数和数据类型必须与 INSERT INTO 指定的列兼容。
  • 示例 (假设要将已完成的考试记录归档):
    INSERT INTO exam_archive (uid, exam_id, start_time, submit_time, score)
    SELECT uid, exam_id, start_time, submit_time, score
    FROM exam_record
    WHERE submit_time IS NOT NULL AND score IS NOT NULL; -- 假设已提交且有成绩
6. 替换插入 (REPLACE INTO)

语法:

REPLACE INTO table_name [(column1, column2, ...)]
VALUES (value1, value2, ...);
  • 说明: 这是 MySQL 特有的扩展语句。它尝试插入新行,如果新行与现有行在主键或唯一索引上发生冲突,则先删除旧行,再插入新行
  • 核心逻辑: REPLACE INTO = DELETE (冲突行) + INSERT (新行)。
  • 优点:
    • 简化逻辑: 一行代码实现“存在则替换,不存在则插入”。
    • 原子性: 操作通常是原子的。
  • 缺点:
    • 性能开销: “删除+插入”比 UPDATE 开销大。
    • 主键变更: 自增主键会获得新值,可能影响外键引用。
    • 非标准: 仅 MySQL/MariaDB 支持,可移植性差。
  • 示例:
    REPLACE INTO examination_info VALUES(NULL, 9003, "SQL", "hard", 90, "2021-01-01 00:00:00");
    • 分析: 假设 exam_id=9003 是唯一键。
      • 若 exam_id=9003 不存在:直接插入,自增主键获新值。
      • 若 exam_id=9003 已存在:先删除旧记录,再插入新记录,自增主键会变成一个新值

总结与最佳实践

  1. 明确指定列名: 始终使用 INSERT INTO table_name (col1, col2, ...) 的形式,避免省略列名列表。这能确保代码的健壮性和可维护性。
  2. 利用部分插入: 当某些列的值可以由数据库自动处理(如 AUTO_INCREMENTDEFAULTNULL)时,使用部分插入是合理且常见的做法(如你的第二个示例)。
  3. 批量插入: 当需要插入多条记录时,优先考虑使用单条 INSERT 语句插入多行,以提高性能。
  4. 数据来源: 除了直接提供值 (VALUES),也要熟悉 INSERT ... SELECT 这种从查询结果插入数据的强大方式。
  5. 注意数据类型: 确保 VALUES 或 SELECT 中的值与目标列的数据类型兼容。你的示例中使用了单引号包裹字符串和日期时间,这是正确的做法。对于数值类型(如 score),通常不需要引号,但加上引号(如 '90')在多数数据库中也会被隐式转换,不过最好遵循数据类型规范。
http://www.dtcms.com/a/312416.html

相关文章:

  • 十八、Javaweb-day18-前端实战-登录
  • JavaScript 性能优化实战指南:从运行时到用户体验的全面提升​
  • 【openlayers框架学习】十:openlayers中控件的使用
  • 学习笔记《区块链技术与应用》第六天 问答 匿名技术 零知识证明
  • Apple基础(Xcode④-Flutter-Platform Channels)
  • Stream 过滤后修改元素,却意外修改原列表
  • Swift 运算符
  • 【Django】-9- 单元测试和集成测试(上)
  • Android 之 蓝牙通信(4.0 BLE)
  • Redis+Lua的分布式限流器
  • C++编译过程与GDB调试段错误和死锁问题
  • 北邮:LLM强化学习架构Graph-R1
  • C++-二叉树OJ题
  • 【反转字符串中的单词】
  • 从零开始设计一个分布式KV存储:基于Raft的协程化实现
  • 吴恩达【prompt提示词工程】学习笔记
  • C# async await 实现机制详解
  • GR-3:字节跳动推出40亿参数通用机器人大模型,精确操作提升250%,开启具身智能新纪元!
  • FasrCGI
  • ospf笔记和 综合实验册
  • visual studio code 怎样将主题修改成亮色,并且配置中文界面
  • zookeeper常见命令和常见应用
  • MySQL——运维篇
  • K8S部署ELK(五):集成Kibana实现日志可视化
  • MySQL面试题及详细答案 155道(021-040)
  • 使用Database Navigator插件进行连接sqlite报错invalid or incomplete database
  • 2025年开关电源行业深度解析:从传统应用到新兴赛道的黄金赛道
  • MVC 发布
  • 代码随想录day53图论4
  • trace-cmd记录线程被中断打断的时间