Вывести результат выполнения SELECT с использованием динамического PL / SQL.

С T-SQL (SQL Server) это не может быть проще:

DECLARE @MyStatement AS NVARCHAR(max) = 'SELECT * FROM MYTABLE'
EXEC (@MyStatement)

Однако использование PL / SQL (Oracle) было настоящей головной болью. Через пару часов я наконец смог достичь того, что было успешно выполнено без ошибок:

declare 
    MyStatement varchar(300) := 'SELECT * FROM MYTABLE';
begin
    execute immediate MyStatement;
end;

Благодаря этому я могу получить успешно завершенную процедуру PL / SQL в окне вывода скрипта. Однако, в отличие от того, что происходит в T-SQL, он не дает мне никакого результата в окне «Результат запроса».

Я попробовал предложенное здесь решение: Как вывести результат оператора SELECT, который выполняется с использованием собственного динамического SQL?, который я все еще не могу воспроизвести. В любом случае, я считаю, что это решение пытается вывести результаты в окно «Вывод сценария». Я ищу не это. Я хочу вывести результаты в окно «Результат запроса».


person Luis Gouveia    schedule 06.04.2017    source источник
comment
Блок PL / SQL выполняется на сервере и не может выводиться напрямую в окно результатов запроса клиента. Есть ли причина, по которой вы не хотите, чтобы это отображалось в выходных данных скрипта (кстати, это можно сделать проще, чем предполагает этот ответ)? Вам нужно будет перепрыгнуть через еще несколько обручей, чтобы включить его в результаты запроса.   -  person Alex Poole    schedule 06.04.2017


Ответы (1)


Когда вы запускаете анонимный блок PL / SQL в своем вопросе, блок компилируется и выполняется нормально, но динамический запрос фактически не выполняется:

Если dynamic_sql_statement является оператором SELECT, и вы опускаете и into_clause, и bulk_collect_into_clause, то execute_immediate_statement никогда не выполняется.

Если бы вы были счастливы просто увидеть результаты в окне вывода скрипта, вы могли бы использовать клиентские команды variable и print SQL Developer и заставить ваш блок открывать указатель ссылки в качестве переменной связывания:

var rc refcursor

declare 
    MyStatement varchar(300) := 'SELECT * FROM MYTABLE';
begin
    open :rc for MyStatement;
end;
/

print rc

Такой подход с привязанным курсором может использоваться другими клиентами, например из приложения Java с использованием JDBC. И 12c добавляет механизм, чтобы немного упростить это, но только из хранимой процедуры - не из анонимного блока. Вы по-прежнему будете видеть только результаты в окне вывода скрипта. хотя (при условии, что ваша версия SQL Developer вообще поддерживает этот механизм).

Я не думаю, что есть какой-либо способ получить результат динамического запроса, запущенного в анонимном блоке, в окнах результатов запроса SQL Developer, поскольку SQL Developer не выполняет запрос - это происходит внутри контекста PL / SQL на сервере. .

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

Трудно сказать, что посоветовать, поскольку ваш пример не должен быть динамичным. Реальный сценарий может предложить другие подходы. Это все еще не совсем то окно результатов запроса, которое вы хотели, но если у вас есть такая функция, как:

функция сброса myfunc;

create function myfunc return sys_refcursor
as
    MyStatement varchar(300) := 'SELECT * FROM MYTABLE';
    MyRefCursor sys_refcursor;
begin
    open MyRefCursor for MyStatement;
    return MyRefCursor;
end;
/

затем вы можете открыть функцию из обозревателя объектов (под подключением на панели слева). Оттуда вы можете щелкнуть зеленый треугольник (или нажать Ctrl-F10), чтобы запустить функцию. Это дает вам окно с предварительно заполненным анонимным блоком для вызова функции:

введите описание изображения здесь

Когда вы нажимаете ОК, результаты динамического запроса попадают в раздел «выходные переменные» (в данном случае используется запрос к таблице сотрудников):

введите описание изображения здесь

Этот вывод не такой гибкий, как окно результатов запроса, хотя, например, вы не можете его экспортировать или отсортировать. Но он в красивой сетке ...

person Alex Poole    schedule 06.04.2017