POSTGRES ERROR: INTO используется с командой, которая не может вернуть данные - PullRequest
0 голосов
/ 05 ноября 2018

Я пытаюсь выполнить переменную t_ord, которая имеет оператор «REVOKE role_test FROM test». Мое требование состоит в том, чтобы выполнить переменную t_ord и сохранить результат msg успешно или неудачно в переменной ret. Но я получаю ошибку ниже,

ОШИБКА: INTO используется с командой, которая не может вернуть данные КОНТЕКСТ: функция PL / pgSQL inline_code_block строка 9 в EXECUTE

    DO $$
 declare
  t_ord varchar(500):= NULL;
  cursor_name numeric;
  ret varchar(500):= NULL;
 begin
SELECT 'REVOKE '||'role_test'||' FROM '||'test' INTO STRICT t_ord ;
raise notice 't_ord %',t_ord;
/*
 cursor_name := DBMS_SQL.OPEN_CURSOR;
      DBMS_SQL.PARSE(cursor_name, t_ord, DBMS_SQL.V7);
      ret      := DBMS_SQL.EXECUTE(cursor_name);
      DBMS_SQL.CLOSE_CURSOR(cursor_name);
*/
EXECUTE t_ord ; -- > not getting desired results as commented code above , cursor_name should be used which is required later in exception block

EXCEPTION
/*   WHEN err THEN
      RAISE EXCEPTION '%', t_msg;
   WHEN OTHERS THEN
         IF DBMS_SQL.IS_OPEN(cursor_name) THEN
            DBMS_SQL.CLOSE_CURSOR(cursor_name);
         END IF;
    RAISE;
*/
  WHEN SQLSTATE '50001' THEN
      RAISE NOTICE '%', t_msg;
WHEN OTHERS THEN
        IF EXISTS(SELECT * FROM pg_cursors WHERE name = 'cursor_name') THEN
        CLOSE cursor_name;
     END IF;
END;

 end $$;

И, как я могу реализовать cursor_name таким же образом в оракуле, чтобы его можно было использовать в блоке исключений ..

1 Ответ

0 голосов
/ 05 ноября 2018

Это слишком долго для комментария.

Декларация cursor_name numeric; не имеет для меня никакого смысла. Если вам нужен курсор (который здесь, кажется, не нужен для начала), вы должны объявить его как cursor, а не numeric. Вы также никогда не открываете курсор для начала. И DBMS_SQL.PARSE не является стандартной функцией Postgres, похоже, вы пытаетесь перенести некоторый код Oracle.

Вы также ссылаетесь на переменную t_msg, которую вы не объявили. Но сообщение об ошибке текущей ошибки автоматически доступно в переменной SQLERRM

Существует также ( документировано ) SQLSTATE 50001 в Postgres, поэтому я не уверен, какую ошибку вы хотите отлавливать там.

Насколько я могу судить, ваш код можно упростить до:

DO $$
declare
  t_ord text;
begin
   -- no need for a SELECT to assign a variable
   t_ord := 'REVOKE role_test FROM test';

   raise notice 't_ord %', t_ord;

   EXECUTE t_ord;
EXCEPTION
  WHEN OTHERS THEN
    RAISE NOTICE '%', SQLERRM;
END;
$$;

Для начала вам не нужен динамический SQL, но я предполагаю, что вы упростили ваш пример. Чтобы сгенерировать правильный оператор REVOKE в блоке PL / pgSQL, вы должны использовать format для правильной обработки идентификаторов в операторах SQL, например, при условии, что у вас есть переменные с именами t_role_name и t_user_name, вы должны использовать что-то вроде:

t_ord := format('REVOKE %I FROM %I', t_role_name, t_user_name);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...