Как выполнить результаты dbms_output.put_line

Существует таблица, содержащая такие данные: select to_char(sysdate,'day') from dual в столбце. Я хочу получить результаты каждого запроса, который хранится в таблице.

Мой набор результатов должен быть результатом select to_char(sysdate,'day') from dual запрос. Так что в этом случае это вторник.

SO_SQL_BODY - это Varchar2.

Я написал этот код, но он возвращает только данные таблицы.

CREATE  or replace PROCEDURE a_proc
AS

 CURSOR var_cur IS

select  SO_SQL_BODY FROM SO_SUB_VARS group by SO_SQL_BODY;

var_t  var_cur%ROWTYPE;

   TYPE var_ntt IS TABLE OF var_t%TYPE;

var_names  var_ntt;
BEGIN
OPEN  var_cur;
FETCH var_cur BULK COLLECT INTO var_names;
CLOSE var_cur;

FOR indx IN 1..var_names.COUNT LOOP

   DBMS_OUTPUT.PUT_LINE(var_names(indx).SO_SQL_BODY);

END LOOP;
END a_proc;

3 ответа

Решение
DECLARE
   res varchar2(4000);
   sql_str varchar2(1000);
BEGIN
  FOR r IN
    (select  SO_SQL_BODY FROM SO_SUB_VARS  WHERE SO_SQL_BODY IS NOT NULL
  )
  LOOP
     sql_str := r.SO_SQL_BODY;
     EXECUTE immediate sql_str INTO res;
     dbms_output.put_line(sql_str);
     dbms_output.put_line('***********************');
     dbms_output.put_line(res);
     dbms_output.put_line('***********************');
  END LOOP;
END;
/

Попробуйте это - выполнить итерацию, чтобы отличные от нуля записи - выполнить их и распечатать результат. Этот скрипт работает, предполагая тот факт, что SO_SQL_BODY содержит запрос, который проецирует только один столбец. Также, если проекция имеет более двух столбцов, попробуйте использовать refcursor и пакет dbms_sql

Если var_names(indx).SO_SQL_BODY вывод - исполняемый текст sql;

CREATE  or replace PROCEDURE a_proc
AS

 CURSOR var_cur IS

select  SO_SQL_BODY FROM SO_SUB_VARS group by SO_SQL_BODY;

var_t  var_cur%ROWTYPE;

   TYPE var_ntt IS TABLE OF var_t%TYPE;

var_names  var_ntt;
BEGIN
OPEN  var_cur;
FETCH var_cur BULK COLLECT INTO var_names;
CLOSE var_cur;

FOR indx IN 1..var_names.COUNT LOOP

   DBMS_OUTPUT.PUT_LINE(var_names(indx).SO_SQL_BODY);
   EXECUTE IMMEDIATE var_names(indx).SO_SQL_BODY;
END LOOP;
END a_proc;

Вам не нужен полный курсор для этого примера. Неявный сделал бы это намного короче.

create or replace procedure a_proc is
        lReturnValue varchar2(250);
    begin
        for q in (select so_sql_body from so_sub_vars group by so_sql_body)
        loop

            execute immediate q.so_sql_body into lReturnValue;
            dbms_output.put_line(lReturnValue);

        end loop;
    end a_proc;

Вы должны добавить обработчик исключений, который будет заботиться о случаях, когда в вашей таблице есть неверный SQL-запрос. Также обратите внимание, что выполнение запросов, сохраненных в таблице базы данных, является вашей точкой входа в SQL-инъекцию.

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