Будет ли удален столбец, если он будет удален из information_schema.columns?

Я использую Postgres 14. Я знаю о ALTER TABLE DROP COLUMN. Но этот вариант в моем случае не работает.

Равны ли эти два запроса:

ALTER TABLE <some_table_1>
    DROP COLUMN IF EXISTS <column_1>,
    DROP COLUMN IF EXISTS <column_2>;
ALTER TABLE <some_table_2>
    DROP COLUMN IF EXISTS <column_1>,
    DROP COLUMN IF EXISTS <column_2>;

И

DELETE FROM information_schema.columns
WHERE table_name IN (<some_table_1>, <some_table_2>)
AND column_name IN (<column_1>, <column_2>)

Или ALTER TABLE выполняет дополнительную работу? Я хочу использовать DELETE FROM, потому что мне действительно нужны такие фильтры, как WHERE в удалении столбцов.

Что происходит, когда вы пытаетесь это сделать?

Bohemian 03.05.2023 02:26

у меня ошибка Views that do not select from a single table or view are not automatically updatable.

Prosto_Oleg 03.05.2023 02:28

Правильно, так что ваш вопрос спорный; невозможно выполнить код, о последствиях которого вы спрашиваете. Кроме того, вам никогда не следует даже думать о взломе таблиц каталога. Используйте API, предоставленный для задачи, то есть оператор alter.

Bohemian 03.05.2023 02:40

Какие фильтры вам нужны для удаления столбцов? Вместо того, чтобы просто заявить, что конкретный вариант не подходит для ваших нужд, постарайтесь объяснить требования и причины, по которым этот вариант неприемлем. Если бы оператор DELETE был исполняемым, он был бы функционально идентичен паре операторов ALTER TABLE, поэтому ничто в вопросе не демонстрирует обоснования отказа от операторов ALTER TABLE.

JohnH 03.05.2023 03:33
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы не можете DELETE строки из любого представления в информационной схеме . Это было бы нонсенсом по многим причинам. К сведению, представления в информационной схеме не являются частью системных каталогов. Но вы также не связываетесь напрямую с системными каталогами, даже если это возможно. Одно неверное движение, и вы можете сломать свою базу данных (кластер). Используйте специальные команды DDL.

Вы ищете динамический SQL, который может быть основан либо на информационной схеме, либо на системных каталогах. У каждого есть плюсы и минусы. Видеть:

В моей реализации используются системные каталоги:

CREATE OR REPLACE PROCEDURE public.my_column_drop(_tbls text[]
                                                , _cols text[]
                                                , _schema text = 'public')
  LANGUAGE plpgsql AS
$proc$
DECLARE
   _tbl regclass;
   _drops text;
BEGIN
   FOR _tbl IN
      SELECT c.oid
      FROM   pg_catalog.pg_class c
      WHERE  c.relkind = 'r'  -- only plain tables (?)
      AND    c.relnamespace = _schema::regnamespace
      AND    c.relname = ANY (_tbls)
   -- more filters HERE
   LOOP
   -- RAISE NOTICE '%', _tbl;
      SELECT INTO _drops
             string_agg(format('DROP COLUMN IF EXISTS %I', a.attname), ', ')
      FROM   pg_catalog.pg_attribute a
      WHERE  a.attrelid = _tbl
      AND    a.attname = ANY (_cols)
      AND    NOT a.attisdropped
      AND    a.attnum > 0
   -- more filters HERE
      ;

      IF _drops IS NOT NULL THEN
      -- RAISE NOTICE '%',  concat_ws(' ', 'ALTER TABLE', _tbl, _drops);
         EXECUTE concat_ws(' ', 'ALTER TABLE', _tbl, _drops);
      ELSE
         RAISE NOTICE 'Table % has no candidate columns', _tbl;
      END IF;
   END LOOP;
END
$proc$;

Вызов:

CALL public.my_column_drop ('{some_table_1,some_table_2}', '{column_1, column_2}');

Попытка удалить столбцы завершается неудачно, если есть какие-либо зависимости. Моя простая функция не проверяет их. Вам нужно будет определить, что проверять и что делать в случае зависимостей...

Процедуры были добавлены в Postgres 11. Вы можете сделать то же самое с функцией в более старых версиях. Или с помощью команды DO для одноразового использования в любой версии. Видеть:

Основы для такого динамического SQL:

Добавление IF EXISTS кажется излишним после того, как мы проверили существование столбца. Имеет смысл только в том случае, если несколько транзакций могут одновременно манипулировать столбцами, что кажется крайне странным случаем.

Другие вопросы по теме