在SQL中,可以将SELECT语句嵌套在INSERT语句的VALUES子句中吗?

时间:2018-08-15 20:18:16

标签: mysql sql

在SQL中,是否可以将SELECT语句嵌套在INSERT语句的VALUES子句中?我正在使用MySQL,并且想在创建新记录时查询表中字段的最大值加1,如下所示。

INSERT into attornies (
  LawOfficeId, LawOfficeName
) VALUES (
  (select max(LawOfficeID)+1 from attornies), 
  'Wee, Sue Em and Howe'
);

我不确定我的语法是否不好,我尝试做的事情是不可能的,等等。当然,如果我将它作为两个单独的语句来尝试,它可以工作,但我想使其成为一个语句。我知道一个建议是使用自动增量,但是我不想。

如果这个问题已经回答,请指出我的方向。如果没有....帮助。

4 个答案:

答案 0 :(得分:6)

是的,你可以做到

INSERT into attornies (
  LawOfficeId, LawOfficeName
)
select max(LawOfficeID) + 1,'Wee, Sue Em and Howe' from attornies;

但是不建议在自动增量中使用此方法,因为如果多个线程进行插入操作,您很可能会遇到重复的主键情况

答案 1 :(得分:2)

您的查询应该可以使用。 values的{​​{1}}子句中允许标量子查询。

通常,它通常写为:

insert

但是,这不是执行您想要的正确方法。而是使用自动增量列创建insert into attornies (LawOfficeId, LawOfficeName) select max(LawOfficeID)+1, 'Wee, Sue Em and Howe' from attornies; (我将其重命名为attornies,因为这似乎是出于意图)

lawOffices

然后执行:

create table lawOffices (
    lawOfficeId int auto_increment primary key,
    lawOfficeName varchar(255)
);

数据库负责增加ID。

答案 2 :(得分:2)

您不能使用显示的语法。

mysql> INSERT into attornies (
    ->   LawOfficeId, LawOfficeName
    -> ) VALUES (
    ->   (select max(LawOfficeID)+1 from attornies), 
    ->   'Wee, Sue Em and Howe'
    -> );
ERROR 1093 (HY000): You can't specify target table 'attornies' for update in FROM clause

https://dev.mysql.com/doc/refman/8.0/en/subquery-errors.html说:

  

您可以在UPDATE语句中使用子查询进行分配,因为子查询在UPDATE和DELETE语句以及SELECT语句中都是合法的。但是,子查询FROM子句和更新目标不能同时使用同一表(在本例中为表t1)。

该文档讨论的是在UPDATE语句中使用子查询,但是在INSERT或DELETE语句中应用相同的规则。

但是,这可行:

mysql> INSERT into attornies (
    ->   LawOfficeId, LawOfficeName
    -> )
    -> select max(LawOfficeID) + 1,'Wee, Sue Em and Howe' from attornies;
Query OK, 1 row affected (0.02 sec)
Records: 1  Duplicates: 0  Warnings: 0

https://dev.mysql.com/doc/refman/8.0/en/insert-select.html说:

  

INSERT语句的目标表可能出现在查询的SELECT部分​​的FROM子句中。但是,您不能插入表并在子查询中从同一表中选择。

     

从同一个表中进行选择并插入时,MySQL创建一个内部临时表来保存SELECT中的行,然后将这些行插入目标表中。

我同意其他警告和评论,它们警告您不要使用MAX()+1方法获取下一个id值。这种方法容易受到比赛条件的影响。请改用自动递增列。

答案 3 :(得分:0)

好的,你们都说服了我。另外,我使用MySQL中的自动递增字段对导入/导出进行了一些测试。我的担心不再合理。我将不必要的max()+ 1想法抛弃,然后自动递增。

我还要感谢史蒂夫,比尔·卡文(Bill Karwin)和戈登·利诺夫(Gordon Linoff)纠正我的SQL,并在我继续最初的想法的情况下指出正确的方向。