象山县本地信息网

SQL 插入数据示例详解

2026-04-09 09:34:02 浏览次数:0
详细信息

SQL 插入数据示例详解

SQL 中的 INSERT 语句用于向数据库表中插入新记录。以下是各种插入数据的详细示例和说明。

1. 基本语法

1.1 插入单行数据(指定列)

-- 基本语法
INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);

-- 示例:向 employees 表插入数据
INSERT INTO employees (employee_id, first_name, last_name, email, hire_date, job_id, salary)
VALUES (101, 'John', 'Doe', 'john.doe@company.com', '2023-01-15', 'IT_PROG', 75000);

1.2 插入单行数据(所有列)

-- 如果为所有列提供值,可以省略列名
INSERT INTO employees
VALUES (102, 'Jane', 'Smith', 'jane.smith@company.com', '2023-02-20', 'SA_REP', 65000, NULL, NULL, 80);

-- 注意:值必须与表结构中的列顺序完全一致

2. 多种插入方式

2.1 插入多行数据

-- 方式1:使用多个VALUES子句
INSERT INTO employees (employee_id, first_name, last_name, email, hire_date, job_id, salary)
VALUES 
    (103, 'Mike', 'Johnson', 'mike.j@company.com', '2023-03-10', 'IT_PROG', 80000),
    (104, 'Sarah', 'Williams', 'sarah.w@company.com', '2023-04-05', 'HR_REP', 55000),
    (105, 'Tom', 'Brown', 'tom.b@company.com', '2023-05-12', 'MK_REP', 60000);

2.2 从其他表插入数据

-- 基本语法
INSERT INTO table2 (column1, column2, ...)
SELECT column1, column2, ...
FROM table1
WHERE condition;

-- 示例:将高薪员工复制到 managers 表
INSERT INTO managers (manager_id, first_name, last_name, salary)
SELECT employee_id, first_name, last_name, salary
FROM employees
WHERE salary > 70000;

-- 示例:插入计算值
INSERT INTO salary_history (employee_id, year, annual_salary, bonus)
SELECT 
    employee_id,
    EXTRACT(YEAR FROM hire_date),
    salary * 12,
    CASE 
        WHEN salary > 70000 THEN salary * 0.15
        ELSE salary * 0.10
    END
FROM employees
WHERE hire_date < '2023-06-01';

3. 插入带有特殊值的数据

3.1 插入 NULL 值

-- 直接使用 NULL 关键字
INSERT INTO employees (employee_id, first_name, last_name, email, hire_date, job_id, salary, manager_id)
VALUES (106, 'Lisa', 'Davis', 'lisa.d@company.com', '2023-06-01', 'SA_REP', 58000, NULL);

-- 或者省略该列(如果列允许NULL)
INSERT INTO employees (employee_id, first_name, last_name, email, hire_date, job_id, salary)
VALUES (107, 'Robert', 'Wilson', 'robert.w@company.com', '2023-07-15', 'IT_PROG', 72000);

3.2 插入默认值

-- 使用 DEFAULT 关键字
INSERT INTO products (product_id, product_name, price, in_stock, created_date)
VALUES (1001, 'Laptop', 999.99, DEFAULT, DEFAULT);

-- 假设 in_stock 默认值为 0,created_date 默认值为 CURRENT_TIMESTAMP

3.3 插入当前日期和时间

-- MySQL/PostgreSQL
INSERT INTO orders (order_id, customer_id, order_date, status)
VALUES (5001, 123, NOW(), 'PENDING');

-- SQL Server
INSERT INTO orders (order_id, customer_id, order_date, status)
VALUES (5002, 456, GETDATE(), 'PROCESSING');

-- Oracle
INSERT INTO orders (order_id, customer_id, order_date, status)
VALUES (5003, 789, SYSDATE, 'SHIPPED');

4. 复杂插入示例

4.1 插入带有子查询的数据

-- 插入带有计算和条件的数据
INSERT INTO employee_stats (department_id, avg_salary, employee_count, last_updated)
SELECT 
    department_id,
    AVG(salary) AS avg_salary,
    COUNT(*) AS employee_count,
    CURRENT_DATE
FROM employees
GROUP BY department_id;

-- 插入存在条件的子查询结果
INSERT INTO high_performers (employee_id, performance_score, reward_amount)
SELECT 
    e.employee_id,
    p.performance_score,
    CASE 
        WHEN p.performance_score >= 90 THEN 5000
        WHEN p.performance_score >= 80 THEN 2000
        ELSE 500
    END
FROM employees e
INNER JOIN performance_reviews p ON e.employee_id = p.employee_id
WHERE p.review_date >= '2023-01-01';

4.2 插入 JSON 数据(现代数据库)

-- PostgreSQL JSON 插入
INSERT INTO user_profiles (user_id, profile_data)
VALUES 
    (1, '{"name": "Alice", "age": 30, "preferences": {"theme": "dark", "notifications": true}}'),
    (2, '{"name": "Bob", "age": 25, "preferences": {"theme": "light", "notifications": false}}');

-- MySQL JSON 插入
INSERT INTO product_details (product_id, specifications)
VALUES 
    (1001, '{"brand": "Dell", "ram": "16GB", "storage": "512GB SSD"}');

5. 带有约束的插入处理

5.1 处理重复键(INSERT ... ON DUPLICATE KEY UPDATE)

-- MySQL:如果存在重复键则更新
INSERT INTO users (user_id, username, email, login_count)
VALUES (101, 'alice123', 'alice@email.com', 1)
ON DUPLICATE KEY UPDATE 
    login_count = login_count + 1,
    last_login = NOW();

-- PostgreSQL:使用 ON CONFLICT
INSERT INTO users (user_id, username, email, login_count)
VALUES (101, 'alice123', 'alice@email.com', 1)
ON CONFLICT (user_id) 
DO UPDATE SET 
    login_count = users.login_count + 1,
    last_login = CURRENT_TIMESTAMP;

5.2 忽略重复插入

-- MySQL:使用 IGNORE
INSERT IGNORE INTO unique_users (user_id, username)
VALUES (101, 'alice123'), (102, 'bob456');

-- PostgreSQL:使用 ON CONFLICT DO NOTHING
INSERT INTO unique_users (user_id, username)
VALUES (101, 'alice123'), (102, 'bob456')
ON CONFLICT (user_id) DO NOTHING;

6. 实际应用示例

6.1 电商系统插入订单

-- 插入订单表
INSERT INTO orders (order_id, customer_id, order_date, total_amount, status)
VALUES (10001, 5001, '2023-10-15 14:30:00', 299.97, 'PENDING');

-- 插入订单详情
INSERT INTO order_items (order_id, product_id, quantity, unit_price)
VALUES 
    (10001, 2001, 1, 199.99),
    (10001, 2002, 2, 49.99);

6.2 博客系统插入文章

-- 插入文章
INSERT INTO articles (article_id, title, content, author_id, category_id, created_at)
VALUES 
    (1001, 'SQL 入门教程', '这是 SQL 入门教程的内容...', 101, 5, NOW()),
    (1002, '数据库设计原则', '数据库设计的最佳实践...', 102, 5, NOW());

-- 插入标签关联
INSERT INTO article_tags (article_id, tag_id)
SELECT 1001, tag_id FROM tags WHERE tag_name IN ('SQL', '数据库', '教程')
UNION
SELECT 1002, tag_id FROM tags WHERE tag_name IN ('数据库', '设计', '最佳实践');

7. 性能优化建议

7.1 批量插入

-- 使用多值语法(推荐)
INSERT INTO products (product_id, product_name, price)
VALUES 
    (1, 'Product A', 10.99),
    (2, 'Product B', 19.99),
    (3, 'Product C', 29.99);
-- 比分别执行三个INSERT语句快得多

7.2 禁用索引和约束(大型插入时)

-- MySQL:禁用/启用索引
ALTER TABLE large_table DISABLE KEYS;
-- 执行大量INSERT操作
ALTER TABLE large_table ENABLE KEYS;

-- PostgreSQL:使用事务
BEGIN;
-- 禁用触发器(如果需要)
ALTER TABLE large_table DISABLE TRIGGER ALL;
-- 执行插入
INSERT INTO large_table ...;
-- 重新启用
ALTER TABLE large_table ENABLE TRIGGER ALL;
COMMIT;

8. 常见错误及解决方法

8.1 列数不匹配

-- 错误:列数不匹配
INSERT INTO employees (employee_id, first_name, last_name)
VALUES (108, 'Anna');  -- 缺少一个值

-- 正确:要么提供所有列的值,要么明确指定列
INSERT INTO employees (employee_id, first_name, last_name, email, hire_date, job_id)
VALUES (108, 'Anna', 'Taylor', 'anna.t@company.com', '2023-08-01', 'HR_REP');

8.2 数据类型不匹配

-- 错误:字符串插入数字列
INSERT INTO products (product_id, product_name, price)
VALUES ('ABC123', 'Test Product', 'NOT_A_NUMBER');  -- price应该是数字

-- 正确:确保数据类型匹配
INSERT INTO products (product_id, product_name, price)
VALUES ('ABC123', 'Test Product', 29.99);

总结

基本插入:使用 INSERT INTO ... VALUES 语法 多行插入:使用多值语法提高性能 从查询插入:使用 INSERT ... SELECT 从其他表获取数据 处理重复:使用 ON DUPLICATE KEY UPDATEON CONFLICT 处理冲突 性能考虑:批量插入、适当禁用索引可以优化性能 错误处理:注意列数匹配、数据类型和约束条件

根据具体的数据库系统(MySQL、PostgreSQL、SQL Server、Oracle等),语法可能略有不同,建议查阅相应数据库的官方文档。

相关推荐