PostgreSQL последний вставленный идентификатор не автоматически увеличивает продолжение машинописного текста

#node.js #typescript #postgresql #sequelize.js

#node.js #typescript #postgresql #sequelize.js

Вопрос:

Пользователь (идентификатор: номер, имя: строка pk)

Как я могу получить самый большой последний идентификатор для вставки нового? Цель состоит в том, чтобы взять предыдущий идентификатор и добавить значение, но идентификатор не является автоинкрементным. Я думал о создании запроса для получения последнего идентификатора, но я надеюсь, что может быть другое оптимизированное предложение

Спасибо

Комментарии:

1. Вы должны определить его как identity (или, по крайней мере serial ,) столбец.

2. Я не могу определить его ни как серийный номер, ни как идентификатор, потому что он не должен быть автоинкрементным. есть какие-либо подсказки?

3. Вы можете создать последовательность в PostgreSQL и использовать ее в качестве значения по умолчанию. В Sequelize вы должны указать autoIncrement: true

4. Брать предыдущий идентификатор (запрос для получения последнего идентификатора) и добавлять значение — плохая идея из-за MVCC.

Ответ №1:

Вы можете делать то, что хотите. Но только потому, что вы можете что-то сделать, это не значит, что вы должны. Я повторяю, вы должны использовать серийный номер или идентификатор. @Stefanov.sm является ли corrent в среде MVCC это очень плохая идея; потому что это виртуальная гарантия, что в какой-то момент вы получите дубликат.
Один из способов получить это — написать функцию для выполнения вставки. Эта функция получает значение MAX (ID) приращение. Он также обрабатывает повторяющуюся ошибку и при необходимости повторяет попытку вставки.

 create or replace 
function establish_user (user_name_in text ) 
 returns integer 
language plpgsql
as $
declare
   k_id_inc    constant integer := 1;  
   l_id        integer;  
   l_inserted  boolean = false; 
begin 
    select coalesce(max(id)   k_id_inc)    
      into l_id 
      from users;
    
    while not l_inserted
    loop
        begin 
            insert into users (id, name) 
                 values (l_id, user_name_in);
                 
            l_inserted  = true; 
        exception 
            when others then 
               if sqlstate != '23505' 
               or sqlerrm not like '%users_id_uk%'
               then 
                   raise;
               else
                   l_id = l_id   1;
               end if;
        end;  
    end loop; 

    return l_id; 
end;
$; 
 

Смотрите демонстрацию здесь.