Подтвердить что ты не робот

Можно ли вывести инструкцию SELECT из блока PL/SQL?

Как получить блок PL/SQL для вывода результатов оператора SELECT так же, как если бы я сделал простой SELECT?

Например, как сделать SELECT как:

SELECT foo, bar FROM foobar;

Подсказка:

BEGIN
SELECT foo, bar FROM foobar;
END;

не работает.

4b9b3361

Ответ 1

Это зависит от того, для чего вам нужен результат.

Если вы уверены, что будет только одна строка, используйте неявный курсор:

DECLARE
   v_foo foobar.foo%TYPE;
   v_bar foobar.bar%TYPE;
BEGIN
   SELECT foo,bar FROM foobar INTO v_foo, v_bar;
   -- Print the foo and bar values
   dbms_output.put_line('foo=' || v_foo || ', bar=' || v_bar);
EXCEPTION
   WHEN NO_DATA_FOUND THEN
     -- No rows selected, insert your exception handler here
   WHEN TOO_MANY_ROWS THEN
     -- More than 1 row seleced, insert your exception handler here
END;

Если вы хотите выбрать более одной строки, вы можете использовать явный курсор:

DECLARE
   CURSOR cur_foobar IS
     SELECT foo, bar FROM foobar;

   v_foo foobar.foo%TYPE;
   v_bar foobar.bar%TYPE;
BEGIN
   -- Open the cursor and loop through the records
   OPEN cur_foobar;
   LOOP
      FETCH cur_foobar INTO v_foo, v_bar;
      EXIT WHEN cur_foobar%NOTFOUND;
      -- Print the foo and bar values
      dbms_output.put_line('foo=' || v_foo || ', bar=' || v_bar);
   END LOOP;
   CLOSE cur_foobar;
END;

или используйте другой тип курсора:

BEGIN
   -- Open the cursor and loop through the records
   FOR v_rec IN (SELECT foo, bar FROM foobar) LOOP       
   -- Print the foo and bar values
   dbms_output.put_line('foo=' || v_rec.foo || ', bar=' || v_rec.bar);
   END LOOP;
END;

Ответ 2

Вы можете сделать это в Oracle 12.1 или выше:

declare
    rc sys_refcursor;
begin
    open rc for select * from dual;
    dbms_sql.return_result(rc);
end;

У меня нет DBVisualizer для тестирования, но это, вероятно, должно быть вашей отправной точкой.

Дополнительные сведения см. в разделе "Неявные наборы результатов" в Руководстве по новым функциям Oracle 12.1, Oracle Base и т.д.

Для более ранних версий, в зависимости от инструмента, вы можете использовать переменные привязки курсора ref, как в этом примере из SQL * Plus:

set autoprint on

var rc refcursor

begin
    open :rc for select count(*) from dual;
end;
/

PL/SQL procedure successfully completed.


  COUNT(*)
----------
         1

1 row selected.

Ответ 3

Создайте функцию в пакете и верните SYS_REFCURSOR:

FUNCTION Function1 return SYS_REFCURSOR IS 
       l_cursor SYS_REFCURSOR;
       BEGIN
          open l_cursor for SELECT foo,bar FROM foobar; 
          return l_cursor; 
END Function1;

Ответ 4

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

Если вы можете использовать именованную процедуру, используйте конвейерные функции. Вот пример, извлеченный из документации:

CREATE PACKAGE pkg1 AS
  TYPE numset_t IS TABLE OF NUMBER;
  FUNCTION f1(x NUMBER) RETURN numset_t PIPELINED;
END pkg1;
/

CREATE PACKAGE BODY pkg1 AS
-- FUNCTION f1 returns a collection of elements (1,2,3,... x)
FUNCTION f1(x NUMBER) RETURN numset_t PIPELINED IS
  BEGIN
    FOR i IN 1..x LOOP
      PIPE ROW(i);
    END LOOP;
    RETURN;
  END;
END pkg1;
/

-- pipelined function is used in FROM clause of SELECT statement
SELECT * FROM TABLE(pkg1.f1(5));

Ответ 5

Классический 'Hello World!' Блок содержит исполняемый раздел, который вызывает процедуру DBMS_OUTPUT.PUT_LINE для отображения текста на экране:

BEGIN
  DBMS_OUTPUT.put_line ('Hello World!');
END;

Вы можете оформить заказ здесь:http://www.oracle.com/technetwork/issue-archive/2011/11-mar/o21plsql-242570.html

Ответ 6

если вы хотите увидеть выбор вывода запроса в pl/sql, вам нужно использовать явный курсор. Это будет содержать активный набор данных и выборка каждой строки за раз, пока она будет отображать всю запись из активного набора данных, если она извлекает данные из набора данных, итерации в цикле. Эти данные не будут генерироваться в табличном формате, этот результат будет в текстовом формате. Надеюсь, это будет полезно. Для любого другого запроса вы можете спросить....

set serveroutput on;
declare
cursor c1 is
   select foo, bar from foobar;
begin
  for i in c1 loop
    dbms_output.put_line(i.foo || ' ' || i.bar);
  end loop;
end;

Ответ 7

Для версий ниже 12c простой ответ НЕТ, по крайней мере, не так, как это делается, это SQL Server.
Вы можете распечатать результаты, вы можете вставлять результаты в таблицы, вы можете возвращать результаты в виде курсоров из функции/процедуры или возвращать набор строк из функции -
 но вы не можете выполнять инструкцию SELECT, не делая ничего с результатами.


SQL Server

begin
    select 1+1
    select 2+2
    select 3+3
end

/* 3 возвращенных набора результатов */


Oracle

SQL> begin
  2  select 1+1 from dual;
  3  end;
  4  /
select * from dual;
*
ERROR at line 2:
ORA-06550: line 2, column 1:
PLS-00428: an INTO clause is expected in this SELECT statement

Ответ 8

Вам нужно использовать собственный динамический SQL. Кроме того, для запуска команды SQL не требуется BEGIN-END:

declare
  l_tabname VARCHAR2(100) := 'dual';
  l_val1    VARCHAR2(100):= '''foo''';
  l_val2    VARCHAR2(100):= '''bar''';
  l_sql     VARCHAR2(1000);  
begin
  l_sql:= 'SELECT '||l_val1||','||l_val2||' FROM '||l_tabname;
  execute immediate l_sql;
  dbms_output.put_line(l_sql);
end;
/

Output:
 SELECT 'foo','bar' FROM dual

Ответ 9

использовать немедленную инструкцию

like:

declare
 var1    integer;
var2 varchar2(200)
begin
 execute immediate 'select emp_id,emp_name from emp'
   into var1,var2;
 dbms_output.put_line(var1 || var2);
end;

Ответ 10

Даже если вопрос старый, но я поделюсь решением, которое идеально ответит на вопрос:

SET SERVEROUTPUT ON;

DECLARE
    RC SYS_REFCURSOR;
    Result1 varchar2(25);
    Result2 varchar2(25);
BEGIN
    OPEN RC FOR SELECT foo, bar into Result1, Result2 FROM foobar;
    DBMS_SQL.RETURN_RESULT(RC);
END;

Ответ 11

Курсоры используются, когда ваш запрос на выборку возвращает несколько строк. Таким образом, вместо использования курсора, если вам нужны агрегаты или отдельные строки, вы можете использовать процедуру/функцию без курсора, например,

  Create Procedure sample(id 
    varchar2(20))as 
    Select count(*) into x from table 
    where 
       Userid=id;
     End ;

А потом просто вызовите процедуру

   Begin
   sample(20);
   End

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