2014-01-26 3 views
0

У меня есть такой запрос, чтобы перечислить таблицы в текущей базе данных:PostgreSQL, падение таблицы с запросом

SELECT c.relname 
FROM pg_catalog.pg_class c 
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace 
WHERE c.relkind 
IN ('r','') AND n.nspname NOT IN ('pg_catalog', 'pg_toast') AND 
pg_catalog.pg_table_is_visible(c.oid) 

Я пытаюсь отбросить все эти таблицы, используя верхний ВЫБРАТЬ как подзапрос:

DROP TABLE IF EXISTS (SELECT c.relname 
FROM pg_catalog.pg_class c 
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace 
WHERE c.relkind 
IN ('r','') AND n.nspname NOT IN ('pg_catalog', 'pg_toast') AND 
pg_catalog.pg_table_is_visible(c.oid)) as tname 

Но что не работают.
Как правильно написать запрос, который выведет все таблицы, перечисленные показанным запросом SELECT?
На данный момент я использую DataReader для обработки результатов запроса и отбрасывания таблиц на единицу.
Но я думаю, что это может пойти «сразу».

+1

Если ваше намерение удалить все объекты пользователя , это можно сделать гораздо проще, используя 'drop, принадлежащий your_pg_username' –

+0

Hm, для этих таблиц владельцем является« postgres ». Это может закончиться хорошо? Я также хотел бы удалить свои пользовательские функции, поэтому получение его с подзапросом будет более полезным для моих целей. –

+1

Как правило, не рекомендуется использовать суперпользователя (postgres), чтобы создать свой собственный материал - и это одна из причин. Другая (более важная) причина заключается в том, что это означает, что ваше приложение подключается к базе данных с привилегиями суперпользователя, которое является открытым отверстием безопасности. –

ответ

4

Вам необходимо использовать динамический SQL для этого, в свою очередь, может быть использован только в процедурном языке, как PL/PgSQL, что-то вроде этого:

do 
$$ 
declare 
    stmt text; 
    table_rec record; 
begin 
    for table_rec in (SELECT c.relname as tname 
        FROM pg_catalog.pg_class c 
         LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace 
        WHERE c.relkind IN ('r','') 
         AND n.nspname NOT IN ('pg_catalog', 'pg_toast') 
         AND pg_catalog.pg_table_is_visible(c.oid)) 
    loop 
    execute 'drop table '||table_rec.tname||' cascade'; 
    end loop; 
end; 
$$ 
+0

Никогда прежде не вижу, что мне нужно попробовать, если он работает с .NET, и он работает. Это удалит все нужные таблицы. Итак, таким же образом я пытаюсь удалить свои пользовательские функции «execute» drop function '|| func_rec.fname ||' Каскад ";» но получаю ошибку: ОШИБКА: Ошибка синтаксиса или вблизи «Каскад» ЛИНИЯ 1: снижение функции first_agg каскад ^ QUERY: снижение функции first_agg каскада КОНТЕКСТ: PL/PgSQL функция inline_code_block линии 14 в EXECUTE заявление. Может быть видно отсюда, почему это происходит? –

+1

@ user973238: 'drop function' не имеет опции' cascade'. Но 'drop owned' позаботится обо всем этом для вас. –

+0

Это может привести к одной и той же проблеме, поскольку все функции снова принадлежат «postgres». Я могу успешно отказаться от функции с «каскадом» из pgAdmin, иначе не могу. Во всяком случае, для удаления пользовательских функций я создал новый вопрос. Не стесняйтесь присоединяться :) и благодарю вас за помощь. –

Смежные вопросы