Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何获取PostgreSQL序列中的下一个数字_Sql_Postgresql_Postgresql 9.4 - Fatal编程技术网

如何获取PostgreSQL序列中的下一个数字

如何获取PostgreSQL序列中的下一个数字,sql,postgresql,postgresql-9.4,Sql,Postgresql,Postgresql 9.4,我想为PostgreSQL做些什么。我明白在PostgreSQL中,作者不会阻止读者。那么,如何安全地增加表中的序列呢。我知道PostgreSQL有一个序列功能,但我不想找它,因为这样我就可以在数据库中创建数千个序列 我有一张这样的桌子: +----+-----------+------+-------+--+ | id | Part | Seq | Model | | +----+-----------+------+-------+--+ | 1 | Head |

我想为PostgreSQL做些什么。我明白在PostgreSQL中,作者不会阻止读者。那么,如何安全地增加表中的序列呢。我知道PostgreSQL有一个序列功能,但我不想找它,因为这样我就可以在数据库中创建数千个序列

我有一张这样的桌子:

+----+-----------+------+-------+--+
| id | Part      | Seq  | Model |  |
+----+-----------+------+-------+--+
| 1  | Head      | 0    | 3     |  |
| 2  | Neck      | 1    | 3     |  |
| 3  | Shoulders | 2    | 29    |  |
| 4  | Shoulders | 2    | 3     |  |
| 5  | Stomach   | 5    | 3     |  |
+----+-----------+------+-------+--+
对于型号3,如何在
gast
之后插入另一条带有下一个seq的记录。下面是新表的外观:

+----+-----------+------+-------+--+
| id | Part      | Seq  | Model |  |
+----+-----------+------+-------+--+
| 1  | Head      | 0    | 3     |  |
| 2  | Neck      | 1    | 3     |  |
| 3  | Shoulders | 2    | 29    |  |
| 4  | Shoulders | 2    | 3     |  |
| 5  | Stomach   | 5    | 3     |  |
| 6  | Groin     | 6    | 3     |  |
+----+-----------+------+-------+--+

是否有一种方法可以创建一个insert查询,该查询只会给出型号3的最高序号之后的下一个数字。另外,要查找并发安全的内容。

您可以使用
as
关键字在insert语句中查询表。您可以找到完整的语法,但在本例中,您需要的语法是
insert-into()

为了确保其他会话无法运行类似的查询,听起来您需要(SRE)锁。根据文件:

此模式保护表不受并发数据更改的影响,并且是自排他的,因此一次只能有一个会话保存它

SRE锁与其他行独占(RE)锁发生冲突,这些锁是在任何插入期间获得的,但仍允许从表中读取。但是,重锁本身不会阻止其他会话同时执行插入,因此简单的插入不足以防止并发更改

SRE锁通常通过更改表或创建触发器自动获得,但也可以手动创建。您需要在插入之前获得锁,然后通过尽快提交更改来释放它

例如:

begin work;
    lock table my_table in share row exclusive mode;

    insert into my_table
        (id, part, seq, model) as
    select
        max(id) + 1 as id,
        'Next Body Part' as part,
        max(seq) + 1 as seq,
        4 as model
    from
        my_table;
commit work;

需要注意的是,这不会阻止应用程序获取max序列(在上述语句运行之前或运行期间),然后处理该序列并使用该变量创建新的insert语句。(例如,
?如seq
,绑定参数为
$max\u sequence+1
)。为了确保它保持并发,您需要确保在同一个insert语句中获得序列号,或者至少在应用程序具有SRE锁时获得序列号。

有,如果您确实需要,是否有方法锁定特定行?我有一张大桌子,不想把整张桌子都锁上。我想在锁定行时防止读写。听起来你可能需要一个共享独占锁。我已经更新了帖子,以反映这将如何工作。您仍然可以阅读,但是如果您介意最后提到的警告,那么并发性就不会有问题。