使用 SQL 中的巧妙语句以连续方式将列值更改为多条记录
Posted
技术标签:
【中文标题】使用 SQL 中的巧妙语句以连续方式将列值更改为多条记录【英文标题】:Changing a column value to several records in a consecutive fashion using clever statements in SQL 【发布时间】:2022-01-04 17:11:55 【问题描述】:我有一个 Postgres 表,其中有一个订单视图字段,我正在使用带有 express 的 Nodejs
这个订单视图是 INTEGER 类型,并且有 NOT NULL 和 UNIQUE 的约束
插入新记录可能会带来问题,因为如果现有记录的视图顺序为 [1, 2, 3, 4, 5],而新记录的顺序视图为 4,那么当前的4要改成5,当前的5要改成6
(我强制这个订单视图是连续的数字,从前端)
我希望在服务器端执行此插入过程(更新现有记录的订单视图)
我想到的是在终点执行一个循环,通过读取订单视图大于或等于新订单视图的记录,并将其更新为 (current + 1)
另一个问题是另一个表中的相关记录,但我认为可以通过级联更新来进行
有人可以找出一个不需要编写循环的 SQL 语句吗?
拉斐尔
【问题讨论】:
【参考方案1】:您可以在单个语句中完成插入和更新。但首先您需要(很可能)更改唯一约束以使其成为deferrable。
alter table <table name>
drop constraint if exists <order view constraint name>;
alter <table name>
add constraint <order view constraint name>
unique(order_view)
deferrable initially deferred;
Postgres 允许在 cte 中使用 DML,因此现在您可以编写 SQL 语句来完成这两个操作:
with updt as
( update <table name>
set order_view = order_view+1
where order_view >= :new_order_view
)
insert into test (order_view, <other columns list>)
values (:new_order_view, <other columns list values>);
其中 <...> 是适当的名称/值。见demo。以上也可以用作 SQL 过程 - 也在演示处理中插入作为最后一项自动设置适当的值。虽然是一个过程,但它仍然只是单个 SQL 语句,因此可以将其拉出并独立运行。 缺点:
Order_view 指定为 0。结果将重新排序导致跳过 Order_view = 1。 Order_view 指定 > 当前 Max+1。结果按指定存储,因此产生了间隙。 受多用户竞争条件的影响。 所有基于 Max+1 的作业也是如此。【讨论】:
【参考方案2】:几乎从不需要在 SQL 中执行任何类型的“循环”——您只需要考虑您正在使用的行的
在这种情况下:
order_view 小于 4 的行不需要更改 order_view 为 4 或更高的行需要增加 1,以“腾出空间”所以SQL真的很简单:
UPDATE some_table
SET order_view = order_view + 1
WHERE order_view >= 4
【讨论】:
以上是关于使用 SQL 中的巧妙语句以连续方式将列值更改为多条记录的主要内容,如果未能解决你的问题,请参考以下文章