Postgres DROP TABLE с использованием DO DECLARE и EXECUTE

Я пытаюсь удалить таблицы, возвращенные из запроса, используя EXECUTE. Вот пример:

CREATE TABLE test_a (id BIGINT);
CREATE TABLE test_b (id BIGINT);

DO
$f$
DECLARE command TEXT;
BEGIN
SELECT INTO command 'SELECT ARRAY_TO_STRING(ARRAY_AGG($$DROP TABLE $$ || table_name), $$;$$) FROM information_schema.tables WHERE table_name ILIKE $$test%$$';
EXECUTE command;
END;
$f$;

Оператор SELECT возвращает «DROP TABLE test_a; DROP TABLE test_b», который я передаю в объявленную переменную и пытаюсь запустить с помощью EXECUTE, но безрезультатно. Что я делаю не так?

PostgreSQL 9.5.18, скомпилированный Visual C++ build 1800, 64-разрядная версия


person douglas_forsell    schedule 29.10.2019    source источник
comment
К вашему сведению, чтобы назначить этот текст переменной, вы можете просто сделать command := 'your text', нет необходимости выбирать.   -  person 404    schedule 29.10.2019
comment
Это командное выражение не соответствует вашим ожиданиям. Пожалуйста, распечатайте его с RAISE NOTICE, чтобы увидеть, что он на самом деле делает.   -  person 404    schedule 29.10.2019


Ответы (1)


Вы сохраняете строку SELECT ARRAY_TO_STRING ... в этой переменной, а не результат оператора SELECT.

Вы также можете упростить ARRAY_TO_STRING(ARRAY_AGG(..)) до string_agg(), и настоятельно рекомендуется использовать format() для создания динамического SQL, для правильной обработки идентификаторов, которые необходимо заключать в кавычки.

Используйте следующее:

DO
$f$
DECLARE 
  command TEXT;
BEGIN

 SELECT string_agg(format('drop table %I', table_name), ';')
   INTO command
 FROM information_schema.tables 
 WHERE table_name ILIKE 'test%';

 execute command;
END;
$f$;
person a_horse_with_no_name    schedule 29.10.2019