提示:注意并关闭 AUTOCOMMIT

INSERT 命令的动态插入

在页面 INSERT 中,描述了如何使用固定值向表中插入单行数据的基本语法和语义。本文介绍了通过子查询动态化 INSERT 命令的方法。


运行时计算值

示例 1:使用系统常量

可以使用系统提供的常量(如当前日期)来动态生成插入值。

-- 使用 CURRENT_DATE 获取当前日期
INSERT INTO person (id,  firstname,        lastname,    date_of_birth, place_of_birth, ssn,           weight)
VALUES             (101, 'Larry, no. 101', 'Goldstein', CURRENT_DATE,  'Dallas',       '078-05-1120', 95);
COMMIT;

示例 2:使用标量子查询

可以通过标量子查询在运行时基于表中现有的行动态计算值。例如:

-- 使用行数计算下一个 ID(不推荐在实际应用中使用这种方法!)
INSERT INTO person (id,   firstname,        lastname,    date_of_birth,     place_of_birth, ssn,           weight)
VALUES             ((SELECT COUNT(*) + 1000 FROM person),
                   'Larry, no. ?',         'Goldstein', CURRENT_DATE,      'Dallas',       '078-05-1120', 95);
COMMIT;

运行时计算多行

通过表子查询,可以动态计算多个行并在一个 INSERT 语句中插入到表中。这种方法相比基于单行的多次插入,效率更高。

示例 1:复制表中的数据

以下示例将表中的所有现有数据复制到新行中,同时修改了 id 值:

-- 将表中的所有行复制,并增加 id
INSERT INTO person (id,          firstname, lastname, date_of_birth, place_of_birth, ssn, weight)
  SELECT            id + 1100,   firstname, lastname, date_of_birth, place_of_birth, ssn, weight
  FROM   person;
COMMIT;

示例 2:基于旧值动态计算新值

通过子查询动态计算插入的权重值。

-- 根据旧权重值动态计算新权重值
INSERT INTO person (id,          firstname, lastname, date_of_birth, place_of_birth, ssn, weight)
  SELECT            id + 1200,   firstname, lastname, date_of_birth, place_of_birth, ssn,
                    CASE WHEN weight < 40 THEN weight + 10
                         ELSE                  weight +  5
                         END
  FROM   person
  WHERE  id <= 10;  -- 仅对前 10 行执行操作
COMMIT;

示例 3:使用嵌套子查询

展示了更复杂的嵌套子查询用法:

INSERT INTO person (id,          firstname, lastname, date_of_birth, place_of_birth, ssn, weight)
  SELECT            id + 1300,   firstname, lastname, date_of_birth, place_of_birth, ssn,
                    (SELECT CASE WHEN weight < 40 THEN weight + 10
                                 ELSE                  weight +  5
                                 END
                     FROM   person ssq
                     WHERE  sq.id = ssq.id  -- 关联子查询和主查询的行
                    )
  FROM   person sq
  WHERE  id <= 10;  -- 仅对前 10 行执行操作
COMMIT;

此技术常用于生成测试数据。例如,倍增现有表中的数据以进行性能测试。


清理数据库

清理插入的数据时,可以使用以下命令:

DELETE FROM person WHERE id > 100;
COMMIT;
Last modified: Tuesday, 28 January 2025, 1:25 PM