2015-11-21 4 views
0

У меня есть несколько операторов SELECT, которые создаются путем объединения нескольких таблиц. Каждый выбор возвращает одну строку, но от 10 до 20 полей этой строки. Каков самый простой способ сохранить эти данные для последующего использования?PL/SQL SELECT INTO

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

Есть ли хороший способ сделать это?

Глупого примера, так что вы можете получить общую идею

SELECT t1.field1 
, t1.field2 
, t1.field3 
, t1.field4 
, t2.field5 
, t2.field6 
, t2.field7 
, t3.field8 
FROM table1 t1 
JOIN table2 t2 ON something 
JOIN table3 t3 ON something 

Извините за ошибки в моем английском и заранее спасибо

ответ

1

Создать вид из вашего отборного заявления. После этого может ссылаться на запись с использованием одной переменной типа <viewname>%ROWTYPE.

Другим вариантом было бы обернуть выберите в неявном цикле курсора:

DECLARE 
    strvar VARCHAR2(400); -- demo purpose only 
BEGIN 
    -- ... 
    FOR i IN (
     -- ... here goesyour select statement ... 
    ) LOOP 
     strvar := i.field1 || i.field2; -- ... whatever 
    END LOOP; 
    -- ... 
END; 
-- ... 

Еще один вариант заключается в декларации типа записи и переменная запись:

DECLARE 
    TYPE tRec IS RECORD (
     field1 table1.field1%TYPE 
     , field2 table1.field2%TYPE 
     , field3 table1.field3%TYPE 
     , field4 table1.field4%TYPE 
     , field5 table2.field5%TYPE 
     , field6 table2.field6%TYPE 
     , field7 table2.field7%TYPE 
     , field8 table3.field8%TYPE 
    ) 
    r tRec; 
BEGIN 
    -- ... 
    SELECT --... 
    INTO r 
    FROM --... 
     ; 
    -- ... 
END; 
-- ... 
+0

Спасибо за ваш ответ. Я не могу создать представление, не имею привилегий в базе данных. И другое решение, которое я нашел allready, но было сказано, что предварительная работа использования цикла для одного ряда ужасна. Поэтому я надеялся, что есть лучший способ сделать это. – BeRightBack

+0

Я не могу серьезно комментировать проблему производительности, хотя по личному опыту я ожидаю, что «ужасная» производительность в одной строке имеет тенденцию быть безвредной в среде, где большие результирующие множества запрос. Я разработал несколько приложений db с обширной кодовой базой plsql, и этот шаблон никогда не был проблемой - ymmv. – collapsar

+0

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

1

Каждый раз, когда вы сделайте выбор, у вас будет cursor - от этого не избежать.

Представления и явные курсоры - это способ повторного использования операторов выбора. Какой вариант лучше, зависит от случая.

rowtype -attribute - удобный способ создания записей автоматически на основе таблиц/представлений/курсоров. Я думаю, что это самое близкое к вашему требованию, которое может предложить PL/SQL.

create or replace package so51 is 
    cursor cursor1 is -- an example single row query 
    select 
    dual.* -- all table columns included 
    ,'Y' as str 
    ,rownum as num 
    ,sysdate as date_ 
    from dual 
    ; 
    function get_data return cursor1%rowtype; 
end; 
/
show errors 

create or replace package body so51 is 
    -- function never changes when cursor1 changes 
    function get_data return cursor1%rowtype is 
    v_data cursor1%rowtype; 
    begin 
    open cursor1; 
    fetch cursor1 into v_data; 
    close cursor1; 
    return v_data; 
    end; 
end; 
/
show errors 

declare 
    v_data constant so51.cursor1%rowtype := so51.get_data; 
begin 
    -- use only the data you need 
    dbms_output.put_line('v_data.dummy = ' || v_data.dummy); 
    dbms_output.put_line('v_data.str = ' || v_data.str); 
    dbms_output.put_line('v_data.num = ' || v_data.num); 
    dbms_output.put_line('v_data.date_ = ' || v_data.date_); 
end; 
/

Пример запуска

SQL> @so51.sql 

Package created. 

No errors. 

Package body created. 

No errors. 
v_data.dummy = X 
v_data.str = Y 
v_data.num = 1 
v_data.date_ = 2015-11-23 09:42:02 

PL/SQL procedure successfully completed. 

SQL>