Как вернуть значение из оператора INSERT в блок транзакции? - PullRequest
0 голосов
/ 06 апреля 2020

Моя цель - вернуть transaction_start значение. Пробовал возвращать ключевое слово.

Но в транзакции это не работает. В результате нет ошибок. Результат просто не содержит данных.

Есть ли другой способ достижения этой цели?

BEGIN;
DELETE FROM table_for_tests WHERE item_id = '142';
INSERT INTO table_for_tests (item_id, valid, key, value) 
VALUES 
  ('142', tstzrange('1970-01-01T03:00', '1970-01-01T03:00:00.000100', '[)'), 'key1', 'modified value1'), 
  ('142', tstzrange('1970-01-01T03:00', '1970-01-01T03:00:00.000100', '[)'), 'key2', 'modified value2') 
RETURNING lower(transaction) as transaction_start;
COMMIT;

UPD :

table_for_tests схема:

id         | item_id  | valid               | transaction        | key           | value 
BIGSERIAL  | BIGINT   | TSTZRANGE NOT NULL  | TSTZRANGE NOT NULL | VARCHAR(255)  | VARCHAR(255) 

transaction столбец заполняется автоматически по триггеру (posgre sql temporal_tables расширение) при выполнении операции INSERT, UPDATE или DELETE.

Триггер был созданный этим кодом:

CREATE TRIGGER versioning_trigger BEFORE INSERT OR UPDATE OR DELETE ON 
table_for_tests FOR EACH ROW 
EXECUTE PROCEDURE versioning('transaction', 'table_for_tests_history', true);

UPD 2 :

Исходный код trigger function (versioning), от pgAdmin III:

-- Function: public.versioning()

-- DROP FUNCTION public.versioning();

CREATE OR REPLACE FUNCTION public.versioning()
  RETURNS trigger AS
'$libdir/temporal_tables', 'versioning'
  LANGUAGE c VOLATILE STRICT
  COST 1;
ALTER FUNCTION public.versioning()
  OWNER TO postgres;
GRANT EXECUTE ON FUNCTION public.versioning() TO postgres;
REVOKE ALL ON FUNCTION public.versioning() FROM public;
COMMENT ON FUNCTION public.versioning() IS 'System-period temporal table trigger';

Ответы [ 2 ]

0 голосов
/ 10 апреля 2020

Решил эту проблему с помощью JOOQ .

Имеет DSLContext с transactionResult() методом.

Пример:

KeyValuesRecord record = context.transactionResult(tx -> {

tx.dsl().deleteFrom(KEY_VALUES)
            .where(KEY_VALUES.ITEM_ID.eq('142'))
            .execute();

KeyValuesRecord insertResult = tx.dsl().insertInto(KEY_VALUES, KEY_VALUES.ITEM_ID, KEY_VALUES.VALID, KEY_VALUES.VALUE)
        .values(itemId, range, value)
        .returning(KEY_VALUES.TRANSACTION)
        .fetchOne(); 

return insertResult;
});
0 голосов
/ 07 апреля 2020

Сначала указатель. Говорить нам «это не работает» совершенно бесполезно, поскольку мы уже знаем это; если бы это работало, вы бы не просили о помощи. Далее «не возвращаемое значение» не намного лучше. Вы должны сказать, что вы ожидаете и что вы получаете. Если вы получили сообщение об ошибке, опубликуйте его, в противном случае укажите, что вы не получаете сообщение. Вы можете рассмотреть Как спросить . Теперь что касается этой конкретной проблемы. Предложение RETURNING не работает на уровне транзакций, оно работает на уровне строк. Строка возвращается для каждой обработанной строки. Кроме того, в этом пункте требуется, что будет правильным выбором, например * или имя столбца. Попробуйте:

 insert into table_for_tests (item_id, valid, key, value) 
       values 
         ('142', tstzrange('1970-01-01t03:00', '1970-01-01T03:00:00.000100', '[)'), 'key1', 'modified value1'), 
         ('142', tstzrange('1970-01-01t03:00', '1970-01-01T03:00:00.000100', '[)'), 'key2', 'modified value2') 
      returning lower(valid) as transaction_start;

Или, возможно:

with do_ins  as  
     ( insert into table_for_tests (item_id, valid, key, value) 
       values 
         ('142', tstzrange('1970-01-01T03:00', '1970-01-01T03:00:00.000100', '[)'), 'key1', 'modified value1'), 
         ('142', tstzrange('1970-01-01T03:00', '1970-01-01T03:00:00.000100', '[)'), 'key2', 'modified value2') 
      returning lower(valid) as transaction_start
    )
select distinct transaction_start, count(*) over (partition by transaction_start)
  from do_ins;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...