锁定多行但只得到一行作为返回结果
Lock multiple rows but get only one row as returned result
我需要锁定多行,但返回结果只得到一行,例如锁定用户:2,4和7,但只得到用户where id = 2
的数据
嗯,据我了解,有两种可能的方法:
1) 运行 两个不同的查询:
-- get user data and lock that row
SELECT some_column FROM users WHERE id = 2 FOR UPDATE INTO my_var;
-- just lock another rows
SELECT some_column FROM users WHERE id IN(4,7) FOR UPDATE;
2) 使用一个查询,使用 CTE 和 "fake" 更新,例如:
WITH t AS(
UPDATE users
SET some_column = some_column
WHERE id IN(2,4,7)
returning some_column
)
SELECT some_column FROM t WHERE id = 2
INTO my_var;
那么,哪种方式更合适呢?或者可能有更好的方法?
我会使用 CTE,但没有真正的更新:
样本table和数据:
t=# create table su(i int);
CREATE TABLE
t=# insert into su values(1),(2),(3),(4);
INSERT 0 4
select 用于更新三键返回一键:
begin;
with l as (select * from su where i in (1,2,4) for update)
select * from l where i = 2;
BEGIN
i
---
2
(1 row)
正在尝试:
begin; update su set i=i where i = 1;
在不同的会话中等待上面的交易完成,而 where i = 1
则不会。并且 SQL 在第一笔交易中 returns 仅 where i = 2
第二种解决方案更糟糕,因为它执行空闲更新。
如果您想在单个查询中执行此操作,请使用 SELECT ... FOR UPDATE:
WITH t AS (
SELECT id, some_column
FROM users
WHERE id IN(2,4,7)
FOR UPDATE
)
SELECT some_column
FROM t
WHERE id = 2;
我需要锁定多行,但返回结果只得到一行,例如锁定用户:2,4和7,但只得到用户where id = 2
嗯,据我了解,有两种可能的方法:
1) 运行 两个不同的查询:
-- get user data and lock that row
SELECT some_column FROM users WHERE id = 2 FOR UPDATE INTO my_var;
-- just lock another rows
SELECT some_column FROM users WHERE id IN(4,7) FOR UPDATE;
2) 使用一个查询,使用 CTE 和 "fake" 更新,例如:
WITH t AS(
UPDATE users
SET some_column = some_column
WHERE id IN(2,4,7)
returning some_column
)
SELECT some_column FROM t WHERE id = 2
INTO my_var;
那么,哪种方式更合适呢?或者可能有更好的方法?
我会使用 CTE,但没有真正的更新:
样本table和数据:
t=# create table su(i int);
CREATE TABLE
t=# insert into su values(1),(2),(3),(4);
INSERT 0 4
select 用于更新三键返回一键:
begin;
with l as (select * from su where i in (1,2,4) for update)
select * from l where i = 2;
BEGIN
i
---
2
(1 row)
正在尝试:
begin; update su set i=i where i = 1;
在不同的会话中等待上面的交易完成,而 where i = 1
则不会。并且 SQL 在第一笔交易中 returns 仅 where i = 2
第二种解决方案更糟糕,因为它执行空闲更新。
如果您想在单个查询中执行此操作,请使用 SELECT ... FOR UPDATE:
WITH t AS (
SELECT id, some_column
FROM users
WHERE id IN(2,4,7)
FOR UPDATE
)
SELECT some_column
FROM t
WHERE id = 2;