Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / PostgreSQL Новый топик    Ответить
 Проблема UPDATE другие строчки  [new]
Legi
Member

Откуда:
Сообщений: 997
Всем добрый вечер!

Столкнулся с проблемой и пока не понимаю куда именно копать (в код, в настройки таблиц, в настройки БД или еще куда?).

Дано:
1) Самая обычная таблица
CREATE TABLE person.tbl_users
(
    user_id integer NOT NULL,
    user_email text COLLATE pg_catalog."default" NOT NULL,
    user_name text COLLATE pg_catalog."default" NOT NULL,
    date_last_upd timestamp(4) without time zone NOT NULL,
    date_ins timestamp(4) without time zone NOT NULL,
    isd integer NOT NULL DEFAULT 0,
    user_type integer NOT NULL,
    CONSTRAINT "TBL_USERS_pkey" PRIMARY KEY (user_id),
    CONSTRAINT "FK_USER_TYPE" FOREIGN KEY (user_type)
        REFERENCES person.tbl_user_type (user_type_id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
)
WITH (
    OIDS = FALSE
)

Есть еще таблица расширение с атрибутами:
CREATE TABLE person.tbl_user_attr
(
    ua_id integer NOT NULL,
    ua_attr_id integer NOT NULL,
    ua_user_id integer NOT NULL,
    ua_attr_value text COLLATE pg_catalog."default",
    CONSTRAINT "TBL_USER_ATTR_pkey" PRIMARY KEY (ua_id),
    CONSTRAINT "FK_USER_ID" FOREIGN KEY (ua_user_id)
        REFERENCES person.tbl_users (user_id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION,
    CONSTRAINT "FK_USER_TYPE_ID" FOREIGN KEY (ua_attr_id)
        REFERENCES person.tbl_user_attr_type (ua_type_id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
)
WITH (
    OIDS = FALSE
)

2) Есть две функции, которые написаны PLpgSQL.
В одной у меня (упрощаем) банально идет INSERT в основную таблицу и в таблицу расширение:
...
v_new_user_id = (SELECT nextval('person.seq_user_id'));
INSERT INTO person."tbl_users"(user_id, user_email, user_name, date_last_upd, date_ins, isd, user_type)
	VALUES (v_new_user_id, v_par_email, v_par_email, TIMESTAMP(0) 'now', TIMESTAMP(0) 'now', 0, 1);
insert into person."tbl_user_attr" ("ua_id","ua_attr_id","ua_user_id","ua_attr_value")
    VALUES(nextval('public.seq_attr_id'),16,v_new_user_id,'true');
...

Вторая, в случае редактирование атрибутов (вторая таблица):
...
UPDATE person.tbl_user_attr
SET ua_attr_value = par_attr_value
WHERE ua_user_id = par_user_id and ua_attr_id = 11;
...
--проапдейтили значения по конкретному par_user_id и теперь обновить поле даты последнего изменения в первой таблице
UPDATE person.tbl_users
SET date_last_upd= TIMESTAMP(0) 'now'
WHERE user_id = par_user_id and isd = 0;


И в данных первой таблицы я ПЕРИОДИЧЕСКИ вижу, что значения полей с датами (date_last_upd и date_ins ) имеют идентичные значения у нескольких строк соседних (от 2 до 6 строк).

user_iddate_last_upddate_ins
2662019-10-16 14:48:092019-10-16 14:13:21
2652019-10-16 14:50:542019-10-16 14:13:21
2642019-10-14 17:17:402019-10-14 17:17:48
2632019-10-14 17:17:402019-10-14 17:17:48
2622019-10-14 17:17:482019-10-14 17:17:48


В чём может быть проблема? куда копать? Нужен хелп)

Код я пересмотрел несколько раз, ошибочных "не туда" UPDATE не делаю.
17 окт 19, 00:59    [21995961]     Ответить | Цитировать Сообщить модератору
 Re: Проблема UPDATE другие строчки  [new]
Anatoly B
Member

Откуда:
Сообщений: 178
Legi,

now - Текущая дата и время (на момент начала транзакции);
Полагаю использовать clock_timestamp() вместо TIMESTAMP(0) 'now' будет более корректно.
17 окт 19, 09:29    [21996068]     Ответить | Цитировать Сообщить модератору
 Re: Проблема UPDATE другие строчки  [new]
Melkij
Member

Откуда: Санкт-Петербург
Сообщений: 937
melkij=> create table dt (t timestamptz);
CREATE TABLE
melkij=> create function dttest() returns void language plpgsql as $$ begin
melkij$> insert into dt values (TIMESTAMP(0) 'now');
melkij$> end;
melkij$> $$;
CREATE FUNCTION
melkij=> select now(), dttest();
              now              | dttest 
-------------------------------+--------
 2019-10-17 10:04:40.891426+03 | 
(1 строка)

melkij=> select now(), dttest();
              now              | dttest 
-------------------------------+--------
 2019-10-17 10:04:42.666203+03 | 
(1 строка)

melkij=> select now(), dttest();
              now              | dttest 
-------------------------------+--------
 2019-10-17 10:04:45.745877+03 | 
(1 строка)

melkij=> table dt;
           t            
------------------------
 2019-10-17 10:04:41+03
 2019-10-17 10:04:41+03
 2019-10-17 10:04:41+03


TIMESTAMP(0) 'now' - литерал константы. Он вычисляется один раз при разборе текста функции. И это ещё кэш хранимых процедур индивидуальный на каждый backend. Попробуйте записать такое в view - и в самом view будет дата создания view всегда.

Выберите функцию по вкусу: https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-CURRENT
И обратите внимание на Tip в конце раздела, это как раз про то самое.
17 окт 19, 10:10    [21996123]     Ответить | Цитировать Сообщить модератору
 Re: Проблема UPDATE другие строчки  [new]
Legi
Member

Откуда:
Сообщений: 997
Спасибо за ответы.
Пока остановился на этом
clock_timestamp()


понаблюдаю по результатам.
20 окт 19, 23:26    [21998552]     Ответить | Цитировать Сообщить модератору
 Re: Проблема UPDATE другие строчки  [new]
Legi
Member

Откуда:
Сообщений: 997
Делюсь апдейтом наблюдений - пока полет нормальный и подобных проблем не испытываю.

Так же перешел на дату\время текущие не от транзакции, а от текущего момента в других местах - тоже подобная проблема вроде бы ушла.

На случай, если кто-то искал решение по аналогичной проблеме.
25 окт 19, 15:29    [22002738]     Ответить | Цитировать Сообщить модератору
Все форумы / PostgreSQL Ответить