--- title: "07-数据插入(增)" created: 2025-11-25 tags: - 项目筑基 --- # 数据插入(增) ```sql INSERT INTO VALUES ``` ### 一一对应式 按列名插入数据 ```sql INSERT INTO 选课成绩(学号,课程编号) VALUES('U201701002','2017-2018') ``` ### 不指定插入哪个列 按属性个数 全部插入某个表 ```sql INSERT INTO 教师 /*教师表此时有七个属性*/ VALUES('T013','徐强','男','1993-7-1','助教','02','19920701') /*这里要插入七个数据*/ ``` ### 可以插入不止一个 ctrl c ctrl v ```sql INSERT INTO 选课成绩(学号,课堂编号) VALUES('U201701002','2017-2008-2-B009') INSERT INTO 选课成绩(学号,课堂编号) VALUES('U201701003','2017-2008-2-B009') INSERT INTO 选课成绩(学号,课堂编号) VALUES('U201701001','2017-2008-2-B009') ``` 对比编辑前200行 如果少数数据用SSMS 较多数据用INSERT INTO VALUES 复制粘贴 对于新插入的列 那一列该如何插入数据? `INSERT INTO 教师(籍贯)VALUES('江西上饶')`??? 用INSERT INTO是不奏效的 因为需要一一对应 建议使用SSMS逐个加 用T-SQL也是可以的 但是得用到 UPDATE 也就是修改语句 其实这不算插入 当做是变相插入 ```sql UPDATE 教师 SET 籍贯='江西抚州' WHERE 姓名='徐强' ``` ```sql INSERT INTO 教师 VALUES('T018','小宇','男','助教','02','NULL','山东德州') --这样插入的NULL不算 ``` 1.`SELECT * FROM 教师 WHERE 密码 = 'NULL'` 相当于密码为NULL这串单词 2.`SELECT * FROM 教师 WHERE 密码 IS NULL` 不是真正的空 1可以查到现在这种NULL 2才是真正的空值查法 --此空非彼空 ### 对于日期的插入 如果表中设置为date类型 ```sql insert into table1(birth) values ('18-11-2004') ``` 是不合法的 ''内为字符型 与date不匹配 可以使用 `str_to_date('字符串日期','日期格式')` 进行转换 mysql中的日期格式: %Y年(大写) %m月 %d日 %h时 %i分 %s秒 所以对于 date 短日期类型 %Y-%m-%d now()函数是datetime类型 datetime 长日期类型 %Y-%m-%d %h-%i-%s ```sql insert into table1(birth) values (str_to_date('18-11-2004','%d-%m-%Y')) ``` str\_to\_date函数可以把字符串varchar转换成日期date类型数据 通常使用在插入insert方面 因为插入的时候需要一个日期类型的数据 需要该函数将字符串转换成date 如果提供的日期字符串是%Y-%m-%d的格式 就无需使用函数转换(会自动换) ```sql insert into table1(birth) values ('2004-11-18') ``` 等于白学 但起码知道了'2004-11-18'这样插入为什么不会报错 自动换了 与它对应的一个函数 `date_format` ![[image-1821dd78.png]] ### 补充:批量插入 一条语句插多行 上面"可以插入不止一个"是ctrl c ctrl v复制的三条语句 其实一条语句就能插多行 VALUES后面跟多组() 组与组之间逗号隔开 ```sql INSERT INTO 选课成绩(学号,课堂编号) VALUES('U201701002','2017-2008-2-B009'), ('U201701003','2017-2008-2-B009'), ('U201701001','2017-2008-2-B009') ``` 一条语句三行数据 效率比三条语句各插一行高(少了两趟网络往返和解析) ### 补充:从别的表捞数据 INSERT INTO SELECT 插入的数据不一定手打 完全可以从另一张表里查出来直接塞进去 ```sql INSERT INTO 教师备份(编号,姓名,性别) SELECT 编号,姓名,性别 FROM 教师 WHERE 性别='女' ``` 查询出多少行就插多少行 两边的列数和类型对上就行 搬家 备份 分表 都靠这一手 ### 补充:主键撞车了怎么办 插入最烦的就是主键冲突 一报错整条语句报废 MySQL给了三招 第一招 INSERT IGNORE 冲突的跳过 没冲突的照插(无声无息) ```sql INSERT IGNORE INTO 教师 VALUES('T013','徐强','男','1993-7-1','助教','02','19920701') ``` 第二招 REPLACE INTO 冲突了就把旧的那条删了 再把新的插进去(先删后插) ```sql REPLACE INTO 教师 VALUES('T013','徐强','男','1993-7-1','讲师','02','19920701') ``` 第三招 ON DUPLICATE KEY UPDATE 冲突了不删旧记录 直接改指定的列 有则更新 无则插入 这招还有个名字叫upsert ```sql INSERT INTO 教师(编号,姓名,职称) VALUES('T013','徐强','讲师') ON DUPLICATE KEY UPDATE 职称='讲师' ``` 怎么选:重复数据无所谓就IGNORE 想整条换新用REPLACE 只想更新个别字段用upsert ### 补充:自增列也要伺候 表里如果有自增列(AUTO_INCREMENT) 插入时直接跳过它 让它自己长 ```sql INSERT INTO 学生(姓名,性别) VALUES('小宇','男') --学号不用管 自己加 ``` 但数据搬家时学号是定死的 就得显式指定 ```sql INSERT INTO 学生(学号,姓名,性别) VALUES(1001,'小宇','男') ``` 显式塞进去之后 自增计数器会自动跟上 后面从1002继续 不用担心撞号 --- ⬅️ [[06-表的管理|06-表的管理]] 🏠 [[00-数据库|00-数据库]] ➡️ [[08-数据删除(删)|08-数据删除(删)]]