INSERT INTO 小技巧

使用INSERT INTO 插入数据是,除了使用INSERT INTO TABLE_NAME FIELD1,FIELD2..VALUES (VALUE1,VALUE2...)这个语句之外,还可以使用另一种写法。

创建一个表,我们用来举例

CREATE TABLE ld (
  id int(11) NOT NULL,
  name varchar(20) DEFAULT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB;

首先是SELECT 语句,SELECT语句的传统写法规则我们这里不用介绍,只介绍我们需要的。

SELECT ATTRIBUTE1 ATTRIBUTE2 ... FROM TABLE_NAME;

SELECT id,name FROM ld;

1	张三
2	lisi
3	lisiS

FIEDL1,FIELD2为表的字段,当指定的字段不在表中,会报错。

SELECT id,namename FROM ld
> 1054 - Unknown column 'namename' in 'field list'
> Time: 0s

但是当指定的是数字或字符串,则不会报错,而是输出以数字或字符串为字段名,值为数字或字符串的行,行的数量是原来表中已有的行数。如果没有指定相应的表,则会输出以数字或字符串为字段名,值为数字或字符串的一行数据,

SELECT 123,'namemame','456' FROM ld;

123	namemame	456
123	namemame	456
123	namemame	456

结合:

INSERT INTO TABLE_NAME SELECT VALUE1 VALUE2;

INSERT INTO ld SELECT 99,'LD'
> Affected rows: 1
> Time: 0.121s

注意VALUE1 ,VALUE2值为TABLE_NAME的属性类型的值,才可以执行成功,

INSERT INTO ld SELECT 'DD','LD'
> 1366 - Incorrect integer value: 'DD' for column 'id' at row 1
> Time: 0.001s

但是以纯数字组成的字符串,可以看做是INT 类型。

INSERT INTO ld SELECT '66','LD'
> Affected rows: 1
> Time: 0.109s

最终表的数据为:

SELECT * FROM ld;

1	张三
2	lisi
3	lisiS
66	LD
99	LD

注意:有一种从多个表中组合字段到另一个表中的写法,即表的复制,语法格式为:

INSERT INTO TABLE1_NAME ( FIELD1,FIELD2...) SELECT FIELD1,FIELD2... FROM TABLE2_NAME;使用两个表,多个表不适用,

当两个表的结构相同时,直接插入数据即可,可以写成这样:

INSERT INTO TABLE1_NAME SELECT * FROM TABLE2_NAME;

当连个表的结构不同时,需要指定插入的列,同时表1表2必须包含相同类型和字段大小的字段:

INSERT INTO TABLE1_NAME (FIELD1,FIELD2) SELECT FIELD1,FIELD2 FROM TABLE1_NAME;

注意:TABLE_NAME1 必须存在,FIELD1,FIELD2也必须存在,若TABLE_NAME1有主键且不具备自动增长,则FIELD1,FIELD2…中必须包括主键。

 

思考:

INSERT INTO LD(id,name) SELECT id,name FROM LD;

这个语句能够将LD的数据复制,然后再插入到LD表中?

答:不能,因为它复制了表中的数据,但是LD表中的id是主键,不能重复,所以不会成功,如果想实现复制自身,则修改id,使其不为主键即可。

 

<think>我们正在讨论批量插入(batch insert)的语法和使用方法。用户可能希望了解如何在SQL中执行批量插入操作,以提高数据插入的效率。批量插入允许一次性插入多行数据,而不是逐行插入,从而减少与数据库的交互次数,提升性能。 根据常见的SQL语法,批量插入有以下几种方式: 1. **使用`VALUES`子句插入多行**:在一条INSERT语句中指定多组值。 2. **使用`INSERT INTO ... SELECT`**:从另一个表或子查询中选取数据插入。 3. **使用预处理语句(Prepared Statements)和参数绑定**:在编程中,通过绑定多组参数来执行批量插入。 4. **数据库特定的批量插入工具**:如MySQL的`LOAD DATA INFILE`,Oracle的SQL*Loader等。 下面我们将详细说明这些方法,并给出示例。 ### 1. 使用`VALUES`子句插入多行 这是最直接的批量插入方法,适用于一次性插入的行数不是特别多的情况(具体行数限制取决于数据库系统)。 **语法:** ```sql INSERT INTO table_name (column1, column2, ...) VALUES (value1_1, value1_2, ...), (value2_1, value2_2, ...), ... (valueN_1, valueN_2, ...); ``` **示例:** 向`employees`表插入三条记录: ```sql INSERT INTO employees (first_name, last_name, hire_date) VALUES ('John', 'Doe', '2023-01-01'), ('Jane', 'Smith', '2023-02-01'), ('Bob', 'Johnson', '2023-03-01'); ``` ### 2. 使用`INSERT INTO ... SELECT` 当需要从另一个表或查询结果中插入大量数据时,可以使用这种方法。 **语法:** ```sql INSERT INTO table_name (column1, column2, ...) SELECT column1, column2, ... FROM source_table WHERE condition; ``` **示例:** 将`temp_employees`表中所有状态为'active'的员工插入到`employees`表中: ```sql INSERT INTO employees (first_name, last_name, hire_date) SELECT first_name, last_name, hire_date FROM temp_employees WHERE status = 'active'; ``` ### 3. 使用预处理语句(Prepared Statements)和参数绑定 在应用程序中,为了避免SQL注入并提高性能,通常使用预处理语句。通过绑定多组参数,可以实现批量插入。 **示例(使用Python的MySQL连接器):** ```python import mysql.connector data = [ ('John', 'Doe', '2023-01-01'), ('Jane', 'Smith', '2023-02-01'), ('Bob', 'Johnson', '2023-03-01') ] conn = mysql.connector.connect(user='user', password='password', database='test') cursor = conn.cursor() sql = "INSERT INTO employees (first_name, last_name, hire_date) VALUES (%s, %s, %s)" cursor.executemany(sql, data) # 批量执行 conn.commit() cursor.close() conn.close() ``` ### 4. 数据库特定的批量加载工具 对于非常大的数据集,使用数据库提供的专用工具通常更高效。 - **MySQL:`LOAD DATA INFILE`** 从文本文件(如CSV)快速导入数据。 ```sql LOAD DATA INFILE '/path/to/employees.csv' INTO TABLE employees FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 ROWS; -- 如果第一行是标题,则忽略 ``` - **Oracle:SQL*Loader** 使用控制文件和数据文件进行批量加载。 ### 注意事项 - **事务处理**:批量插入时,建议将操作放在一个事务中,这样要么全部成功,要么全部回滚,保证数据一致性。 - **性能**:批量插入可以显著提高性能,但一次性插入的行数不宜过多,以免造成日志过大或锁表时间过长。可以分批插入(如每1000行插入一次)。 - **错误处理**:在批量插入中,如果某一行插入失败,整个插入操作可能会失败(取决于数据库设置和语句)。需要根据错误信息进行排查。 ### 总结 批量插入是提高数据插入效率的重要手段。根据数据量和来源,可以选择合适的批量插入方法。对于应用程序,推荐使用预处理语句的批量操作;对于大文件导入,可以使用数据库提供的专用工具。 §§相关问题§§ 1. 批量插入时如何避免主键冲突? 2. 在批量插入过程中,如何实现分批插入(chunking)以提高效率? 3. 不同数据库(MySQL, Oracle, PostgreSQL)的批量插入语法有何差异? 4. 批量插入操作是否会影响数据库的并发性能?如何优化? [^1]: Oracle retrieves the DEGREE and INSTANCES specifications from the definition of all tables and indexes involved in the query and chooses the highest values found for those settings. [^2]: Oracle can parallelize UPDATE and DELETE statements on partitioned tables, but only when multiple partitions are involved. [^3]: GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,ALTER,CREATE TEMPORARY TABLES,CREATE VIEW,EVENT,TRIGGER,SHOW VIEW,CREATE ROUTINE,ALTER ROUTINE,EXECUTE ON test.* TO 'test'@'localhost' IDENTIFIED BY '111111'</think>### 批量插入(Batch Insert)语法及使用指南 批量插入是高效插入多行数据的 SQL 技术,核心语法如下: #### 1. **标准 VALUES 语法** ```sql INSERT INTO table_name (col1, col2, ...) VALUES (val1_row1, val2_row1, ...), (val1_row2, val2_row2, ...), ...; ``` **示例**:插入 3 条用户记录 ```sql INSERT INTO users (name, email, created_at) VALUES ('Alice', 'alice@example.com', NOW()), ('Bob', 'bob@example.com', NOW()), ('Charlie', 'charlie@example.com', NOW()); ``` #### 2. **INSERT INTO SELECT 语法** ```sql INSERT INTO target_table (col1, col2, ...) SELECT colA, colB, ... FROM source_table WHERE condition; ``` **示例**:从临时表导入数据 ```sql INSERT INTO orders (user_id, product_id, quantity) SELECT user_id, product_id, qty FROM temp_orders WHERE status = 'pending'; ``` #### 3. **数据库特有语法** **MySQL 扩展语法**: ```sql INSERT INTO table SET col1=val1, col2=val2 ON DUPLICATE KEY UPDATE col2=VALUES(col2); ``` **Oracle 批量绑定**(PL/SQL): ```plsql DECLARE TYPE t_tab IS TABLE OF users%ROWTYPE; l_data t_tab; BEGIN l_data := t_tab( users_rec(1, 'Alice', ...), users_rec(2, 'Bob', ...) ); FORALL i IN 1..l_data.COUNT INSERT INTO users VALUES l_data(i); END; ``` #### 4. **性能优化技巧** - **事务批处理**(减少提交次数): ```sql START TRANSACTION; INSERT INTO logs (...) VALUES (...); -- 1000次 COMMIT; -- 统一提交 ``` - **LOAD DATA INFILE**(MySQL 文件导入): ```sql LOAD DATA INFILE '/path/data.csv' INTO TABLE my_table FIELDS TERMINATED BY ','; ``` - **禁用索引**(大数据量场景): ```sql ALTER TABLE my_table DISABLE KEYS; -- 执行批量插入 ALTER TABLE my_table ENABLE KEYS; ``` #### 5. **权限要求** 需拥有目标表的 `INSERT` 权限(参考引用[^3]): ```sql GRANT INSERT ON database.table TO 'user'@'host'; ``` #### 6. **注意事项** 1. **数据验证**:批量插入跳过单行校验,需预先验证数据完整性 2. **错误处理**:部分数据库支持 `IGNORE` 选项忽略错误行 ```sql INSERT IGNORE INTO table ... -- MySQL ``` 3. **并发控制**:Oracle 支持并行插入(参考引用[^2]): ```sql INSERT /*+ APPEND PARALLEL(4) */ INTO sales ... ``` ### 性能对比示例 | 方法 | 10,000 行耗时 | 适用场景 | |----------------------|---------------|-----------------| | 单条 INSERT | 12.8 秒 | 小批量数据 | | VALUES 多行 | 0.9 秒 | 中等批量(≤1000行)| | LOAD DATA INFILE | 0.2 秒 | 超大数据集 | > **关键提示**:当批量插入涉及分区表时,Oracle 可并行化操作(参考引用[^2]),但要求操作**跨多个分区**才能生效。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值