mysql—在sql中,能否在insert语句的values子句中嵌套select语句?

5tmbdcev  于 2021-06-20  发布在  Mysql
关注(0)|答案(4)|浏览(2243)

在sql中,是否可以在insert语句的values子句中嵌套select语句?我使用的是mysql,希望在创建新记录时查询表中字段加1的最大值,如下所示。

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

我不确定我的语法是否不好,我正在尝试做的是不可能的,等等,当然,如果我尝试这两个独立的语句,它可以工作,但我想让它成为一个语句。我知道一个建议是使用自动增量,但我不想。
如果这个问题已经回答了,请给我指出那个方向。如果不是。。。。救命啊。

kulphzqa

kulphzqa1#

好吧,你们都说服我了。另外,我在mysql中使用一个自动递增字段对导入/导出进行了一些测试。我的担心已经没有道理了。我将放弃我的max()+1的想法,认为这是不必要的,并使用自动递增。
我还要感谢steve、bill karwin和gordon linoff,感谢他们纠正了我的sql,并为我指出了正确的方向,如果我继续我最初的想法的话。

dauxcl2d

dauxcl2d2#

是的,你能做到

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

但是,这不建议超过自动增量,因为如果有多个线程在执行插入操作,则很可能会遇到主键重复的情况

xriantvc

xriantvc3#

你不能使用你展示的语法。

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子句和update目标同时使用同一个表(在本例中为表t1)。
doc讨论的是在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值的方法。这种方法易受竞争条件的影响。改为使用自动递增列。

px9o7tmv

px9o7tmv4#

你的查询应该有效。中允许标量子查询 values 合同条款 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)
);

然后做:

insert into lawOffices (lawOfficeName)
    values ( 'Wee, Sue Em and Howe' );

数据库执行递增id的工作。

相关问题