🇯🇵 日本語 | 🇺🇸 English | 🇪🇸 Español | 🇵🇹 Português | 🇹🇭 ไทย | 🇨🇳 中文

【SQL INSERT入门】如何使用INSERT INTO语句向表中添加新数据

网站的用户注册、博客的新帖子、电商网站的商品上架……Web应用之所以充满活力,正是因为新数据在源源不断地产生。而承担“向数据库注册新数据”这一最基本、最重要操作的,就是SQL的INSERT语句。

INSERT语句是向数据库这个巨大的账本中写入新行的命令。它的语法乍一看很简单,但用法却多种多样,从只添加一行,到批量注册多行,再到从其他表复制数据。然而,正因为简单,一点小错误就容易导致失败,也成为初学者容易卡壳的地方。

本文旨在帮助Web开发者们完全掌握INSERT语句。我们将通过大量“即拷即用”的代码,从基本写法到实际应用,再到常见错误及其处理方法,进行全面而详尽的解说。让我们先动手运行代码,感受“数据被成功添加!”的喜悦,以此迈出踏入SQL世界的第一步吧。


准备工作:创建一个用于添加数据的表

要添加数据,首先需要一个存放数据的“盒子”,也就是表。这次,我们来创建一个名为products的表,用于管理新商品的信息。在整篇文章中,我们都将使用这个表。

值得注意的是id列的INTEGER PRIMARY KEY。在许多数据库中(如SQLite,或MySQL中的AUTO_INCREMENT),这样设置后,每次添加数据时,系统都会自动分配一个唯一的ID。这一点在后面会非常重要。

-- 如果products表已存在,则删除(以便重复测试)
DROP TABLE IF EXISTS products;

-- 创建一个新的products表
CREATE TABLE products (
  id INTEGER PRIMARY KEY,
  name TEXT NOT NULL,
  category TEXT,
  price INTEGER,
  release_date DATE
);

这样,一个用于注册商品数据的空表就准备好了。接下来,让我们立刻为这个表注入新的生命力吧。


【基础】INSERT INTO ... VALUES: 添加单行数据

首先是INSERT语句的基本形式:“添加单行数据”的方法。语法是INSERT INTO 表名 (列1, 列2, ...) VALUES (值1, 值2, ...);。重点在于,第一个括号内的列列表与VALUES后的值列表要按顺序一一对应。

INSERT INTO products (name, category, price, release_date)
VALUES ('奇迹苹果', '食品', 500, '2025-07-01');

执行此查询后,products表中会添加一条新商品记录。我们没有指定id列,但由于在创建表时设置了自动编号,数据库会自动为其分配ID1。这是将主键(PRIMARY KEY)设置为自动递增的一大优点。

让我们来确认一下是否添加成功。执行SELECT * FROM products;,应该就能看到刚才添加的数据。

SELECT * FROM products;

执行结果:

id | name     | category | price | release_date
---|----------|----------|-------|-------------
1  | 奇迹苹果 | 食品     | 500   | 2025-07-01

另外,如果某些列的值尚未确定(仅限于允许NULL的列),可以在插入时省略这些列。

-- 插入时省略价格(price)和发布日期(release_date)
INSERT INTO products (name, category)
VALUES ('梦幻桃子', '食品');

在这种情况下,pricerelease_date列将包含NULL(无值)。


【应用1】一次性批量添加多行数据

逐一注册新商品有点麻烦。INSERT语句支持在一次查询中批量添加多条数据。

写法很简单,只需在VALUES关键字后,用逗号(,)分隔多个由()包裹的值列表即可。这样可以减少与数据库的通信次数,比逐行重复执行INSERT语句效率更高。

INSERT INTO products (name, category, price, release_date) VALUES
('魔法键盘', '数码产品', 12000, '2025-07-10'),
('彩虹鼠标', '数码产品', 5000, '2025-07-20'),
('天空葡萄', '食品', 2500, '2025-08-01');

通过这一条查询,三条商品数据就被一次性添加进去了。在投入初始数据或批量注册从CSV文件读取的数据时,这是一个非常方便的技巧。


【应用2】使用`INSERT ... SELECT`语句从其他表复制数据

这是一个面向中级用户且非常强大的技巧。使用INSERT ... SELECT语句,你可以将从另一个表中用SELECT语句查询出的结果,直接添加到新表中

例如,在“将‘新品到货列表’表(new_arrivals)中已确定发售的商品移至products表”这样的场景中,它能大显身手。

首先,让我们创建作为复制源的new_arrivals表,并注册一些数据。

-- 创建源表
CREATE TABLE new_arrivals (
  product_name TEXT NOT NULL,
  product_category TEXT,
  list_price INTEGER,
  launch_date DATE,
  is_confirmed INTEGER -- 如果确定发售则为1,否则为0
);

-- 在新品到货列表中注册数据
INSERT INTO new_arrivals VALUES
('终极耳机', '音频设备', 28000, '2025-09-01', 1),
('未来VR眼镜', '数码产品', 75000, '2025-10-01', 1),
('全自动咖啡机', '家电', 18000, '2025-09-15', 0);

准备好了。现在,让我们从new_arrivals表中选出已确定发售(is_confirmed = 1)的商品,并将其添加到products表中。

INSERT INTO products (name, category, price, release_date)
SELECT product_name, product_category, list_price, launch_date
FROM new_arrivals
WHERE is_confirmed = 1;

此查询的重点是使用SELECT语句代替了VALUES子句。SELECT语句检索的列结构(列的数量、顺序、数据类型)必须与INSERT INTO products (...)中指定的列结构相匹配。这种方法的用途非常广泛,例如数据备份、将聚合结果保存到另一张表等。


初学者常遇到的INSERT语句错误及处理方法

如果违反了数据库的规则(约束),INSERT语句会立即返回错误。在这里,我们来看看初学者常遇到的典型错误、其原因及处理方法。

错误1:主键(PRIMARY KEY)重复

这是最常见的错误。主键是表内绝不能重复的唯一标识符。如果你手动指定ID,并试图再次使用一个已经存在的ID,就会发生错误。

例如,ID=1的“奇迹苹果”已经注册。如果我们再次尝试用ID=1注册一个新商品……

-- 这会导致错误!
INSERT INTO products (id, name, category, price, release_date)
VALUES (1, '另一个苹果', '食品', 300, '2025-07-02');

执行此操作将显示类似UNIQUE constraint failed: products.idDuplicate entry '1' for key 'PRIMARY'的错误消息。

处理方法: 最安全可靠的方法是不要手动管理主键,而是交给数据库的自动编号功能。就像第一个例子那样,在INSERT语句的列列表中不包含id即可。

错误2:违反NOT NULL约束

在创建表时指定为NOT NULL的列必须有值。如果尝试插入时省略了该列,就会发生错误。

products表的name列是NOT NULL。如果我们尝试在不指定name的情况下插入……

-- 这也会导致错误!
INSERT INTO products (category, price)
VALUES ('其他', 1000);

将会显示类似NOT NULL constraint failed: products.name的错误。

处理方法: 对于有NOT NULL约束的列,务必指定某个值。如果希望允许空字符串,则需明确指定为''

错误3:数据类型不匹配

如果你尝试插入与表定义中规定的数据类型不符的数据,就会发生错误。例如,尝试将字符串插入到数值类型(INTEGER)的price列中。

-- 这当然也会导致错误!
INSERT INTO products (name, price)
VALUES ('昂贵的石头', '价格是秘密');

将会出现类似Datatype mismatchIncorrect integer value: '价格是秘密' for column 'price'的错误。

处理方法: 仔细检查表定义,并为每列指定正确数据类型的值。请注意,将数字用引号括起来(如'500')使其变为字符串也是一个常见错误。


【体验环节】在浏览器中运行SQL,添加数据吧!

现在,是时候将知识转化为技能了!将下面的HTML代码完整复制,保存为sql_insert_test.html之类的文件名,然后在浏览器中打开它。你专属的SQL执行环境将会启动,并且本文中创建的products表已经为你准备好了。

你可以自由地编写INSERT语句并点击“执行”按钮,然后在下面紧接着编写SELECT * FROM products;并再次“执行”,来确认数据是否真的被添加了。故意制造一些错误也是很好的学习方式哦!

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>SQL INSERT语句 在线执行环境</title>
  <style>
    body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; line-height: 1.7; color: #333; max-width: 800px; margin: 2rem auto; padding: 0 1rem; }
    h1 { color: #2c3e50; }
    textarea { width: 100%; height: 180px; font-family: "SF Mono", "Consolas", monospace; font-size: 16px; padding: 12px; border: 1px solid #ccc; border-radius: 6px; box-sizing: border-box; margin-bottom: 1rem; }
    button { background-color: #27ae60; color: white; border: none; padding: 12px 22px; font-size: 16px; border-radius: 6px; cursor: pointer; transition: background-color 0.2s; }
    button:hover { background-color: #229954; }
    button:disabled { background-color: #bdc3c7; cursor: not-allowed; }
    #result-container { margin-top: 2rem; border: 1px solid #ddd; padding: 1rem; border-radius: 6px; background: #fdfdfd; min-height: 50px; }
    #status-message { color: #27ae60; font-weight: bold; }
    #error-message { color: #e74c3c; font-weight: bold; }
    table { border-collapse: collapse; width: 100%; margin-top: 1rem; }
    th, td { border: 1px solid #ddd; padding: 10px; text-align: left; }
    th { background-color: #f2f2f2; }
    tr:nth-child(even) { background-color: #f9f9f9; }
  </style>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.10.3/sql-wasm.js"></script>
</head>
<body>

  <h1>来试试SQL吧!</h1>
  <p>在下面的文本框中输入SQL语句,然后点击“执行”按钮。试试插入一个你自己想出来的商品吧!</p>

  <textarea id="sql-input">-- 在这里写下你的INSERT或SELECT语句
INSERT INTO products (name, category, price, release_date) 
VALUES ('无重力椅', '家具', 45000, '2025-11-11');

SELECT * FROM products;
  </textarea>
  
  <button id="execute-btn">执行</button>
  
  <div id="result-container">
    <p id="status-message"></p>
    <p id="error-message"></p>
    <div id="result-output"></div>
  </div>

  <script>
    const sqlInput = document.getElementById('sql-input');
    const executeBtn = document.getElementById('execute-btn');
    const statusMsg = document.getElementById('status-message');
    const errorMsg = document.getElementById('error-message');
    const resultOutput = document.getElementById('result-output');

    let db;

    async function initDb() {
      executeBtn.disabled = true;
      executeBtn.textContent = '数据库准备中...';
      try {
        const SQL = await initSqlJs({
          locateFile: file => `https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.10.3/${file}`
        });
        db = new SQL.Database();
        
        const setupSql = `
          DROP TABLE IF EXISTS products;
          CREATE TABLE products (
            id INTEGER PRIMARY KEY,
            name TEXT NOT NULL,
            category TEXT,
            price INTEGER,
            release_date DATE
          );
        `;
        db.run(setupSql);
        
        executeBtn.disabled = false;
        executeBtn.textContent = '执行';
        statusMsg.textContent = '准备就绪!请尝试用INSERT语句添加数据,并用SELECT语句确认结果。';

      } catch (err) {
        errorMsg.textContent = '数据库初始化失败:' + err.message;
        console.error(err);
      }
    }

    function executeSql() {
      if (!db) return;
      
      const sql = sqlInput.value;
      statusMsg.textContent = '';
      errorMsg.textContent = '';
      resultOutput.innerHTML = '';

      try {
        const statements = sql.split(';').filter(s => s.trim() !== '');
        let lastResult;

        statements.forEach(stmt => {
          const trimmedStmt = stmt.trim();
          if (trimmedStmt.toUpperCase().startsWith('INSERT') || trimmedStmt.toUpperCase().startsWith('UPDATE') || trimmedStmt.toUpperCase().startsWith('DELETE')) {
            db.run(trimmedStmt);
            const changes = db.getRowsModified();
            statusMsg.innerHTML += `查询 “${trimmedStmt.substring(0, 30)}...” 已执行,${changes}行受到影响。<br>`;
          } else {
             const results = db.exec(trimmedStmt);
             lastResult = results;
          }
        });

        if (lastResult && lastResult.length > 0) {
            lastResult.forEach(result => {
            const table = document.createElement('table');
            const thead = document.createElement('thead');
            const tbody = document.createElement('tbody');
            const headerRow = document.createElement('tr');
            result.columns.forEach(colName => {
                const th = document.createElement('th');
                th.textContent = colName;
                headerRow.appendChild(th);
            });
            thead.appendChild(headerRow);
            result.values.forEach(row => {
                const bodyRow = document.createElement('tr');
                row.forEach(cellValue => {
                const td = document.createElement('td');
                td.textContent = cellValue === null ? 'NULL' : cellValue;
                bodyRow.appendChild(td);
                });
                tbody.appendChild(bodyRow);
            });
            table.appendChild(thead);
            table.appendChild(tbody);
            resultOutput.appendChild(table);
            });
        }

      } catch (err) {
        errorMsg.textContent = 'SQL错误:' + err.message;
        console.error(err);
      }
    }

    executeBtn.addEventListener('click', executeSql);
    
    initDb();
  </script>
</body>
</html>

INSERT的伙伴们:CRUD操作

学会了INSERT,你就掌握了数据库操作基本四项能力中的一项。这四项操作的首字母缩写被称为CRUD,是所有应用程序数据操作的基础。

你已经对SELECT很熟悉了。现在你已经可以“添加”数据,下一步可以学习如何“更新”(UPDATE)或“删除”(DELETE)数据,这将进一步拓宽你能用数据库做的事情的范围。


总结

这次,我们详细学习了用于向数据库添加新数据的INSERT语句,内容涵盖了从基础到应用,再到需要注意的错误。

INSERT语句是为你的网站和应用注入生命、记录用户行为、丰富内容的第一步。请在本文的体验环节中反复练习,掌握自由自在地添加数据的感觉。这些微小成功经验的积累,必将引导你成为一名顶尖的Web开发者。