如何使用SQL系列 之 如何在SQL中插入数据
简介
结构化查询语言,通常被称为SQL,在允许您将数据插入表中方面提供了极大的灵活性。例如,你可以使用VALUES关键字指定单独的行数据,使用SELECT查询从现有表中复制整组数据,以及以使SQL自动插入数据的方式定义列。
在本指南中,我们将复习如何使用SQL的INSERT INTO语法添加数据表与这些方法。
前期准备
为了学习本指南,你需要一台运行某种使用SQL的关系数据库管理系统(RDBMS)的计算机。
注意:请注意,许多RDBMS使用它们自己独特的SQL实现。虽然本教程中概述的命令适用于大多数RDBMS,但如果你在MySQL以外的系统上测试它们,确切的语法或输出可能会有所不同。
你还需要一个装载了一些示例数据的数据库和表,可以在其中练习使用相关命令。
连接到MySQL并设置一个示例数据库
如果SQL数据库系统运行在远程服务器上,请从本地设备SSH到服务器:
ssh sammy@your_server_ip
然后打开MySQL服务器提示符,将==sammy==替换为你的MySQL用户账户的名称:
mysql -u sammy -p
创建一个名为insertDB的数据库:
CREATE DATABASE insertDB;
如果数据库成功创建,您将收到这样的输出:
OutputQuery OK, 1 row affected (0.01 sec)
要选择insertDB数据库,运行以下USE语句:
USE insertDB;
OutputDatabase changed
选择insertDB数据库后,在其中创建一个表。举个例子,假设你有一家工厂,想创建一张表来存储员工的一些信息。这个表包含以下5个字段:
name:每个员工的名字,表示使用的varchar数据类型,字符长度30position:这一列将存储每个员工的职位头衔,同样使用不超过30个字符的varchar数据类型表示department:每个员工的部门,表示使用的varchar数据类型,但最多只有20个字符hourlyWage:记录每个员工每小时工资的一列,它使用decimal数据类型,该列中的任何值的长度都限制为最多4位,其中2位在小数点的右侧。因此,这一列允许的取值范围是-99.99到99.99startDate:每个员工被雇佣的日期,使用date数据类型表示。该类型的值必须符合YYYY-MM-DD格式。
创建一个名为factoryEmployees的表,它包含以下5个字段:
CREATE TABLE factoryEmployees (
name varchar(30),
position varchar(30),
department varchar(20),
hourlyWage decimal(4,2),
startDate date
);
有了这些,你就可以开始学习如何使用SQL插入数据了。
手动插入数据
在SQL中插入数据的通用语法如下所示:
INSERT INTO table_name
(column1, column2, . . . columnN)
VALUES
(value1, value2, . . . valueN);
为了说明这一点,运行以下INSERT INTO语句来加载包含一行数据的factoryEmployees表:
INSERT INTO factoryEmployees
(name, position, department, hourlyWage, startDate)
VALUES
('Agnes', 'thingamajig foreman', 'management', 26.50, '2017-05-01');
OutputQuery OK, 1 row affected (0.00 sec)
这条语句以INSERT INTO关键字开始,后面跟着要插入数据表的名称。表名后面是一个字段列表,其中包含了该语句将向其中添加数据的列,这些列被括在括号中。字段列表后面是VALUES关键字,然后是用括号括起来的一组值,用逗号分隔。
列的排列顺序并不重要。重要的是要记住值与列的对应顺序。SQL总是试图插入第一个值为第一列,第二个值到第二列等。为了说明这一点,下面的INSERT语句添加了另一行数据,但以不同的顺序列出了这些列:
INSERT INTO factoryEmployees
(department, hourlyWage, startDate, name, position)
VALUES
('production', 15.59, '2018-04-28', 'Jim', 'widget tightener');
OutputQuery OK, 1 row affected (0.00 sec)
如果没有正确地对齐值与列,SQL可能会将数据写入错误的列。此外,如果任何值与列的数据类型冲突,就会导致错误,如下面的例子所示。
INSERT INTO factoryEmployees
(name, hourlyWage, position, startDate, department)
VALUES
('Louise', 'doodad tester', 16.50, '2017-05-01', 'quality assurance');
OutputERROR 1366 (HY000): Incorrect decimal value: 'doodad tester' for column 'hourlyWage' at row 1
请注意,当你必须提供每一列指定一个值,你不一定需要指定表中的每一列数据当添加一个新的行。只要你忽略的列中没有会导致错误的约束(比如NOT NULL), MySQL就会为未指定的列添加NULL:
INSERT INTO factoryEmployees
(name, position, hourlyWage)
VALUES
('Harry', 'whatzit engineer', 26.50);
OutputQuery OK, 1 row affected (0.01 sec)
如果你计划输入一个包含表中每一列值的行,则根本不需要包含列名。请记住,您输入的值仍然必须与表定义中定义的列的顺序一致。
在这个例子中,列出的值与factoryEmployee表的CREATE TABLE语句中定义的列的顺序一致:
INSERT INTO factoryEmployees
VALUES
('Marie', 'doodad welder', 'production', 27.88, '2018-03-29');
OutputQuery OK, 1 row affected (0.00 sec)
你也可以一次添加多个记录在每一行之间用逗号,就像这样:
INSERT INTO factoryEmployees
VALUES
('Giles', 'gizmo inspector', 'quality assurance', 26.50, '2019-08-06'),
('Daphne', 'gizmo presser', 'production', 32.45, '2017-11-12'),
('Joan', 'whatzit analyst', 'quality assurance', 29.00, '2017-04-29');
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
使用SELECT语句复制数据
你可以使用SELECT查询从一个表中复制多行数据并插入到另一个表中,而不是逐行指定数据。
这种操作的语法如下所示:
INSERT INTO table_A (col_A1, col_A2, col_A3)
SELECT col_B1, col_B2, col_B3
FROM table_B;
在这个例子中,我们没有在列后面加上VALUES关键字,而是在它后面加上了SELECT语句。这个示例语法中的SELECT语句只包含FROM子句,但任何有效的查询都可以工作。
为了说明,运行以下CREATE TABLE操作来创建一个新的名为“showroomEmployees”的表。请注意,这个表的列与上一节中使用的factoryEmployees表中的三个列具有相同的名称和数据类型:
CREATE TABLE showroomEmployees (
name varchar(30),
hourlyWage decimal(4,2),
startDate date
);
OutputQuery OK, 0 rows affected (0.02 sec)
现在你可以通过在INSERT INTO语句中包含SELECT查询来从之前创建的factoryEmployees表中读取一些数据来加载这个新表。
如果SELECT查询返回的相同数量的列顺序相同目标表的列,和他们也有兼容匹配的数据类型,您可以省略字段列表的INSERT INTO声明:
INSERT INTO showroomEmployees
SELECT
factoryEmployees.name,
factoryEmployees.hourlyWage,
factoryEmployees.startDate
FROM factoryEmployees
WHERE name = 'Agnes';
OutputQuery OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0
注意:此操作的SELECT查询中列出的列前都有factoryEmployees表名和一个句点。当你像这样指定一个表名来引用一个列时,它被称为完全限定列引用。在这种特殊情况下,这是不必要的。事实上,下面的INSERT INTO语句示例将产生与前一个相同的结果:
INSERT INTO showroomEmployees
SELECT
name,
hourlyWage,
startDate
FROM factoryEmployees
WHERE name = 'Agnes';
为了清晰起见,本节中的示例使用了完全限定的列引用,但这样做可能是一个好习惯。它们不仅可以帮助您的SQL更容易理解和故障排除,在引用多个表的某些操作中,例如包含JOIN子句的查询,完全限定列引用变得必要。
这个操作中的SELECT语句包含了一个WHERE子句,它导致查询只返回factoryEmployees表中的name列包含值Agnes的行。因为在源表中只有一行这样的记录,所以只有这一行会被复制到showroomEmployees表中。
为了确认这一点,运行以下查询来返回showroomEmployees表中的每条记录:
SELECT * FROM showroomEmployees;
Output+-------+------------+------------+
| name | hourlyWage | startDate |
+-------+------------+------------+
| Agnes | 26.50 | 2017-05-01 |
+-------+------------+------------+
1 row in set (0.00 sec)
任何从源表返回多行数据的查询都可以插入多行数据。例如,以下语句中的查询将返回factoryEmployees数据库中name列的值不以J开头的每条记录:
INSERT INTO showroomEmployees
SELECT
factoryEmployees.name,
factoryEmployees.hourlyWage,
factoryEmployees.startDate
FROM factoryEmployees
WHERE name NOT LIKE 'J%';
OutputQuery OK, 5 rows affected (0.01 sec)
Records: 5 Duplicates: 0 Warnings: 0
再次运行此查询以返回showroomEmployees表中的每条记录:
SELECT * FROM showroomEmployees;
+--------+------------+------------+
| name | hourlyWage | startDate |
+--------+------------+------------+
| Agnes | 26.50 | 2017-05-01 |
| Agnes | 26.50 | 2017-05-01 |
| Harry | 26.50 | NULL |
| Marie | 27.88 | 2018-03-29 |
| Giles | 26.50 | 2019-08-06 |
| Daphne | 32.45 | 2017-11-12 |
+--------+------------+------------+
6 rows in set (0.00 sec)
注意:在name列中有两行相同的Agnes。每次你运行使用SELECT的INSERT INTO语句时,SQL都会将查询结果视为一组新数据。除非你对表施加某些约束,或者开发更细粒度的查询,否则在添加这样的数据时,没有什么能防止数据库加载重复记录。
自动插入数据
在创建表时,可以对列应用某些属性,RDBMS会自动向列填充数据。
为了说明这一点,运行以下声明定义一个名为interns的表,包含3个字段。在这个例子中,第一列internID保存着int类型的数据。但是请注意,它还包含AUTO_INCREMENT属性。这个属性会让SQL自动为每条新记录生成一个唯一的数值,默认从1开始,然后每条记录加1。
类似地,第二列department包含DEFAULT关键字。如果你在 insert INTO语句的字段列表中省略了department, RDBMS会自动插入默认值——本例中是production:
CREATE TABLE interns (
internID int AUTO_INCREMENT PRIMARY KEY,
department varchar(20) DEFAULT 'production',
name varchar(30)
);
注意:AUTO_INCREMENT属性是MySQL特有的特性,但是许多rdbms有自己的递增整数的方法。为了更好地理解你的RDBMS是如何管理自动递增的,你应该查阅它的官方文档。
以下是几个流行的开源数据库的官方文档:
-
MySQL
AUTO_INCREMENT属性文档 -
PostgreSQL
serial数据类型文档 -
SQLite
Autoincrement关键字文档
为了演示这些特性,用一些数据写入interns表通过运行以下INSERT INTO的语句。此操作仅指定name列的值:
INSERT INTO interns (name) VALUES ('Pierre'), ('Sheila'), ('Francois');
OutputQuery OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
Then run this query to return every record from the table:
SELECT * FROM interns;
Output+----------+------------+----------+
| internID | department | name |
+----------+------------+----------+
| 1 | production | Pierre |
| 2 | production | Sheila |
| 3 | production | Francois |
+----------+------------+----------+
3 rows in set (0.00 sec)
这个输出表明,由于列的定义,前面的INSERT INTO语句将值添加到internID和department中,即使没有指定它们。
要给department列添加一个默认值以外的值,你需要在INSERT INTO语句中指定该列,如下所示:
INSERT INTO interns (name, department)
VALUES
('Jacques', 'management'),
('Max', 'quality assurance'),
('Edith', 'management'),
('Daniel', DEFAULT);
OutputQuery OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
请注意,本例中提供的最后一行值包含DEFAULT关键字,而不是字符串值。这将导致数据库插入默认值('production'):
SELECT * FROM interns;
Output+----------+-------------------+----------+
| internID | department | name |
+----------+-------------------+----------+
| 1 | production | Pierre |
| 2 | production | Sheila |
| 3 | production | Francois |
| 4 | management | Jacques |
| 5 | quality assurance | Max |
| 6 | management | Edith |
| 7 | production | Daniel |
+----------+-------------------+----------+
7 rows in set (0.00 sec)
总结
通过阅读本指南,你学习了几种向表中插入数据的不同方法,包括使用VALUES关键字指定单独的行数据,使用SELECT查询复制整个数据集,以及定义SQL将自动插入数据的列。
这里列出的命令应该适用于任何使用SQL的数据库管理系统。记住,每个SQL数据库都使用自己独特的语言实现,因此你应该查阅相应DBMS的官方文档,以更完整地了解它如何处理INSERT INTO语句以及它有哪些可用选项。
相关文章:
如何使用SQL系列 之 如何在SQL中插入数据
简介 结构化查询语言,通常被称为SQL,在允许您将数据插入表中方面提供了极大的灵活性。例如,你可以使用VALUES关键字指定单独的行数据,使用SELECT查询从现有表中复制整组数据,以及以使SQL自动插入数据的方式定义列。 …...
【LeetCode题目详解】1281题 整数的各位积和之差 面试题 01.01. 判定字符是否唯一 python题解(作业一二)
本文章以python为例! 一、力扣第1281题:整数的各位积和之差 问题描述: 1281. 整数的各位积和之差 给你一个整数 n,请你帮忙计算并返回该整数「各位数字之积」与「各位数字之和」的差。 示例 1: 输入:n 234 输出…...
1.12 进程注入ShellCode套接字
在笔者前几篇文章中我们一直在探讨如何利用Metasploit这个渗透工具生成ShellCode以及如何将ShellCode注入到特定进程内,本章我们将自己实现一个正向ShellCodeShell,当进程被注入后,则我们可以通过利用NC等工具连接到被注入进程内,…...
MySQL 日志系统
重要日志模块 日志文件bin logredo log**关于循环写入和擦除的checkpoint 规则**redo log 怎么刷入磁盘的 binlog 和 redo log 有什么区别?undo log 日志文件 错误日志(error log): 错误日志文件对 MySQL 的启动、运行、关闭过程进…...
LeetCode刷题---Two Sum(一)
文章目录 🍀题目🍀解法一🍀解法二🍀哈希表 🍀题目 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每…...
算法通关村第十七关——插入区间
LeetCode435,给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。 示例1: 输入:interva1s[[1,3],[6,9]],newInterva1[2,5] 输出:[[1,5],[6,9]] 解释:新区间[2,5]与[1,3]重…...
Jenkins java8安装版本安装
一、首先准备Jenkins、Jdk8、Tomcat9安装包 根据Jenkins官网介绍,Jenkins支持Java8的版本如下: 我们选择2.164版本进行安装,根据版本号支持输入下载地址:https://archives.jenkins.io/war/2.164/jenkins.war,进行下载…...
线上问诊:数仓开发(二)
系列文章目录 线上问诊:业务数据采集 线上问诊:数仓数据同步 线上问诊:数仓开发(一) 线上问诊:数仓开发(二) 文章目录 系列文章目录前言一、DWS1.最近1日汇总表1.交易域医院患者性别年龄段粒度问诊最近1日汇总表2.交易域医院患者…...
Ansible自动化运维工具(三)
目录 Ansible 的脚本 --- playbook 剧本 编辑2.vars模块实战实例 3.指定远程主机sudo切换用户 4.when模块实战实例 5.with_items迭代模块实战实例 6.Templates 模块实战实例 (1)先准备一个以 .j2 为后缀的 template 模板文件,设置引用…...
ChatGPT在创新和创业中的应用如何?
ChatGPT是一种基于大规模预训练的语言模型,它在创新和创业中有着广泛的应用。作为一种具备自然语言处理能力的模型,ChatGPT可以与用户进行对话,并提供相关的信息、建议和创意。以下是ChatGPT在创新和创业中的一些应用: 创意生成和…...
Log4j2 配置日志记录发送到 kafka 中
前言 log4j2 在 2.11.0 之后的版本,已经内置了 KafkaAppender 支持可以将打印的日志直接发送到 kafka 中,在这之前如果想要集中收集应用的日志,就需要自定义一个 Layout 来实现,相对来说还是比较麻烦的。 官网文档:L…...
Linux用户与组管理(03)(八)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一、组管理 1、概述 2、用户信息查看 总结 前言 今天是学习用户与组管理的最后一节课,这节课主要是组管理的内容,希望能一起学习ÿ…...
Java自定义异常
Java标准库定义的常用异常包括: 当我们在代码中需要抛出异常时,尽量使用JDK已定义的异常类型。例如,参数检查不合法,应该抛出IllegalArgumentException: static void process1(int age) {if (age < 0) {throw new…...
vscode远程调试php
使用vscode远程调试php的方法 1.安装remote ssh插件 2.连接服务器 可以点击左下角的绿色按钮,或者ctrlshiftp打开命令框输入remote ssh应该也有。 3.在服务器端vscode安装php debug插件 4.安装xdebug xdebug是用来调试php的软件,原本和vscode没什么关…...
C语言:截断+整型提升练习
详情关于整型提升与截断见文章:《C语言:整型提升》 一、代码一 int main() { char a -1; signed char b -1; unsigned char c -1; printf("%d %d %d", a, b, c); return 0; } 求输出结果 解析如下代码: int mai…...
Kubernetes技术--k8s核心技术kubectl命令行工具
(1).概述 kubectl是Kubernetes集群的命令行工具,通过 kubectl 能够对集群本身进行管理,并能够在集群上进行容器化应用的安装部署。 (2).语法 Kubectl [command] [type] [name] [flags] 语法参数说明: command: 指定要对资源执行的操作,例如 create、get、describe 和 delet…...
Element浅尝辄止9:Popover 弹出框组件
Popover 的属性与 Tooltip 很类似,它们都是基于Vue-popper开发的,因此有重复属性 1.如何使用? /*trigger属性用于设置何时触发 Popover,支持四种触发方式: hover,click,focus 和 manual。 对于…...
程序开发:构建功能强大的应用的艺术
程序开发是在今天的数字化时代中扮演重要角色的一项技术。通过编写代码,开发人员能创造出无数不同的应用,从简单的计算器到复杂的社交平台。电子商务应用、在线教育平台、医疗记录系统等,都重视程序开发的重要性,通过这其中的交互…...
(七)k8s实战-高级调度
一、CronJob 定时任务 1、cron 表达式 # ┌───────────── 分钟 (0 - 59) # │ ┌───────────── 小时 (0 - 23) # │ │ ┌───────────── 月的某天 (1 - 31) # │ │ │ ┌───────────── 月份 (1 - 12) # │ │ │ │ ┌…...
HTTP/1.1协议中的八种请求
2023年8月29日,周二晚上 目录 概述八种请求GET请求POST请求PUT请求PATCH请求DELETE请求HEAD请求OPTIONS请求TRACE请求 概述八种请求 HTTP/1.1协议中定义了8种常用的请求方法,分别是:1. GET 用途:请求指定的页面信息,并返回实体主体。例子:获取一个网页、图片等静态…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...
Python实现简单音频数据压缩与解压算法
Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...
