#postgresql
#postgresql
Вопрос:
Я пытаюсь создать ddl, чтобы добавить столбец в одну таблицу и заполнить его значениями из другой вновь созданной таблицы в зависимости от логического значения из обновленной таблицы. Поэтому я сначала создаю новую таблицу, заполняю ее необходимыми значениями, затем добавляю столбец в существующую таблицу. Затем я обновляю этот столбец, но это обновление не выполняется, когда я пытаюсь выполнить все в одной транзакции.
Если я выполняю оператор update отдельно после создания таблицы и нового столбца, он работает нормально, поэтому я знаю, что в моем операторе update нет ничего плохого.
Я не понимаю, почему он не выполняется, когда я запускаю все операторы в одной транзакции. Кто-нибудь может помочь?
-- Create the table for the sub types
CREATE SEQUENCE IF NOT EXISTS framework."UserGroupSubType_S";
CREATE TABLE IF NOT EXISTS
framework."UserGroupSubTypes"
(
"UserGroupSubTypeId" INTEGER NOT NULL,
"UserGroupSubType" CHARACTER VARYING(50) NOT NULL,
"Updated" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
CONSTRAINT
"UserGroupSubTypeId_P"
PRIMARY KEY ("UserGroupSubTypeId"),
CONSTRAINT
"UserGroupSubTypes_UserGroupSubType"
UNIQUE ("UserGroupSubType")
)
WITH
(
OIDS = FALSE
);
-- Fill the table with the sub types
INSERT INTO framework."UserGroupSubTypes"
VALUES
(NEXTVAL('"UserGroupSubType_S"'), 'CustomerDefined', NOW()),
(NEXTVAL('"UserGroupSubType_S"'), 'Mandatory', NOW()),
(NEXTVAL('"UserGroupSubType_S"'), 'GeneralAdmin', NOW()),
(NEXTVAL('"UserGroupSubType_S"'), 'Buyer', NOW())
ON CONFLICT DO NOTHING;
-- Add the column to the table "UserGroups"
ALTER TABLE framework."UserGroups" ADD COLUMN IF NOT EXISTS "UserGroupSubTypeId" INTEGER;
-- Update the column with the correct value
UPDATE framework."UserGroups"
SET "UserGroupSubTypeId" = (CASE
WHEN "IsMandatory" = TRUE
THEN (SELECT "UserGroupSubTypeId" FROM framework."UserGroupSubTypes" WHERE "UserGroupSubType" = 'Mandatory')
WHEN "IsMandatory" = FALSE
THEN (SELECT "UserGroupSubTypeId" FROM framework."UserGroupSubTypes" WHERE "UserGroupSubType" = 'CustomerDefined')
END);
Я пробовал другие способы обновления, например, устанавливал значение по умолчанию равным 1, а затем обновлял только те, для которых требуется другое значение, но, похоже, ничего не работает.
Столбец не обновляется никогда.
Комментарии:
1. Во-первых, почему бы и нет
"UserGroupSubTypeId" SERIAL PRIMARY KEY
, то же самое дляUNIQUE
on"UserGroupSubType"
. Во-вторых, я не вижуBEGIN/COMMIT
указаний на то, что это все одна транзакция? В-третьих, если это действительно в транзакции, просматриваете ли вы обновленную таблицу из другого сеанса доCOMMIT
? Если это так, вы не увидите изменений. В-четвертых, отображаются ли в журналах Postgres какие-либо ошибки, когда это происходит?2. Что касается первичного ключа и ограничения уникальности, это просто способ, которым он настроен в компании, поэтому я не могу это изменить. Начало фиксации обрабатывается в другой части кода, поэтому я уверен, что все эти операторы обрабатываются в одних и тех же транзакциях. Я также пробовал это в pgAdmin, с тем же результатом. Что касается вашего третьего пункта, если бы это было так, я бы не увидел никаких изменений? Я вижу новую таблицу, я вижу новый столбец, но значения столбцов по-прежнему равны НУЛЮ
3. Не имеет отношения к вашей проблеме, но: вам действительно следует избегать этих страшных идентификаторов в кавычках. Они доставляют гораздо больше хлопот, чем того стоят. wiki.postgresql.org/wiki /…
4. Я знаю, но иногда вы должны следовать правилам компании: p
Ответ №1:
По-видимому, pgAdmin не обрабатывает группу выбранных операторов как одну транзакцию. Благодаря комментарию Adrain я попытался добавить
BEGIN;
---
---
COMMIT;
вокруг операторов, и это решило проблему. Теперь столбец правильно заполнен значениями из вновь созданной таблицы.
Спасибо, Адриан, за вашу помощь
Комментарии:
1. Рад, что это сработало. В pgAdmin я предполагаю, что вы используете инструмент запроса. Если это так, рядом со значком выполнения должен быть значок с пометкой / . Нажмите на это и посмотрите, установлены ли флажки автоматической фиксации и / или автоматического отката. Похоже, автоматическая фиксация была / не проверена.
2. Я первым делом проверю в понедельник, спасибо за совет