mysql - MariaDB/MySQL 中的 CTE 中类似 PostgreSQL 的返回修改语句管道/使用
问题描述
试图insert .. returning ..
在 MariaDB/MySQL 中找到一种不复杂的方式来管道/链接返回修改语句(例如)。这是有效的 PostgreSQL 代码:
创建 2 个表:
create table test1(
id serial primary key,
value int
);
create table test2(
ref_id int,
value varchar
);
使用with
,将 的输出通过管道传输insert .. returning ..
到另一个insert
:
with
cte as (
insert into test1(value)
select floor(random()*10) as value
returning *
)
insert into test2(ref_id, value)
select
id,
concat('Inserted value is ', value::varchar) as value
from cte
;
编辑:为简单起见,该示例仅插入一行,但一般用例将插入多行(通常至少数千行)。要模拟真实世界的用例,请添加from generate_series(1,1000000)
到select
.
test1
测试从(由公平掷骰子选择)返回 (1, 4)和 (1, 'Inserted value is 4') 从test2
(注意 1 intest2
是预先由 's 序列/自动增量动态生成的test1
,不能指定为文字)。
这在需要修改以某种方式逻辑连接的单独表中的数据时非常有用(例如,插入一个值,返回一个串行/自动增量 id,然后将该 id 作为引用插入到其他表中)。我通常会在 PostgreSQL 中以这种方式链接十几个插入和更新:
with
cte1 as (insert .. returning ..),
cte2 as (update .. from cte1 .. returning ..),
cte3 as (delete .. from cte2 .. returning ..)
...
但是,with
似乎仅限select
于 MariaDB 中的 CTE,因此基本上一次仅限于一个修改语句,并且无法通过管道insert .. returning ..
进入进一步的语句(不,子查询也不起作用)。
有没有办法在没有外部工具的情况下完成此操作(例如通过 PHP 存储返回值,然后发出进一步的语句,如果查询正在处理数千或数百万行,这可能会产生可怕的性能)?
请记住,如果插入的行没有严格的唯一键,则可能无法保证以后正确选择插入的行(尤其是不断写入表),因此insert .. returning ..
在我的用例。
迄今为止研究的潜在解决方案
insert .. returning ..
(MariaDB 10.5+) 返回 ID 但不能用作 CTE 或子查询。我也找不到将结果集存储到临时表或变量中的方法,这可以通过引用临时表的后续语句轻松解决问题。
解决方案
MySQL/MariaDB 不支持returning
或类似的,所以你必须在这里运行多个语句。
但是,您可以使用last_insert_id()
来恢复最后一个自动生成的值,因此您可以执行以下操作:
insert into test1(value)
values (floor(rand() * 10));
insert into test2 (ref_id, value)
select id, value
from test1
where id = last_insert_id();
推荐阅读
- python - 试图在列中扩展嵌套的字典列表
- c# - 如何按下 datagridview1 中的链接并转到另一个表单?
- php - 如何为实体(例如页面)制作关系树以在用户界面上显示它?
- c# - rdlc 报告在 VS 中运行良好,但在它部署的客户端上运行良好
- jquery-ui-sortable - 应用 sortableJS 后列表项中的字符串
- macos - 无法在具有单声道版本 5.0+ 的 Mac 上安装 nant
- python - Windows Python 反向外壳,连接但没有交互
- apache-spark - 如何从 PySpark 中的数据框中获取模式定义?
- r - 访问 lapply 中的行号
- java - 使用 toSplit() 方法拆分后如何使用字符串声明人员对象?