2015-11-21 119 views
0

我有几个SELECT语句是通过连接多个表来完成的。 每个select都返回单行,但从该行中的10到20个字段。存储该数据以供日后使用的最简单方法是什么?PL/SQL SELECT INTO alternative

我想避免创建50个变量和写入select语句,使用游标和单行循环不是我读到的最聪明的想法。

有没有很好的方法来做到这一点?

愚蠢的例子,让你可以大致了解

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

创建一个从你的SELECT语句的视图。此后可以通过使用<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

谢谢您的回答。我无法创建视图,没有数据库权限。我已经发现了其他的解决方案,但被告知使用单行循环的性能非常糟糕。所以我希望有更好的办法做到这一点 – BeRightBack

+0

虽然我个人的经验我不能认真评论性能问题,但我认为在一个单行中的“糟糕”性能往往在大型结果集环境下无害查询。我已经联合开发了几个带有广泛的plsql代码库的数据库应用程序,并且该模式从未成为问题 - ymmv。 – collapsar

+0

您可以在plsql中定义一个可以接收记录的单个记录变量。但是,您必须定义记录类型及其所有组件,这些组件有效地等于列的各个变量的声明。如果这是可行的,看看更新的答案中的代码示例。 – collapsar

1

每次做一个选择你将有一个cursor - 有没有逃避。

视图和显式游标是重用select语句的一种方式。哪一个更好选择取决于案例。

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>