Plsql 在存储过程中重用大型SQL查询

Plsql 在存储过程中重用大型SQL查询,plsql,Plsql,我想在PL/SQL包中使用许多长SQL select查询(150行以上)。该包具有执行SQL查询和将结果插入单独表、将SQL结果与另一个表进行比较、删除行等过程 使用以下工具存储SQL结果相当容易: INSERT into TABLE1 SELECT .... (150 line ugly select query goes here) 问题是,我想将select SQL存储在游标/函数/视图/任何可用的文件中,这样我就不必将150行查询粘贴到使用SQL的每个过程中 我可以将SQL存储为游标,

我想在PL/SQL包中使用许多长SQL select查询(150行以上)。该包具有执行SQL查询和将结果插入单独表、将SQL结果与另一个表进行比较、删除行等过程

使用以下工具存储SQL结果相当容易:

INSERT into TABLE1
SELECT .... (150 line ugly select query goes here)
问题是,我想将select SQL存储在游标/函数/视图/任何可用的文件中,这样我就不必将150行查询粘贴到使用SQL的每个过程中

我可以将SQL存储为游标,然后在包过程中循环游标,获取每一行并插入到表中。但考虑到我使用游标的唯一动机是减少我的包中的行数,这似乎效率很低

有没有更好的方法可以在不同的过程中调用SQL select查询,而无需复制和粘贴所有150行?如果这是一个脚本,我会将SQL存储在一个文本文件中,然后将文本文件读入一个变量,并在需要时将该变量传递给sqlplus。但是我对PL/SQL不是很熟悉

代码:


我不确定这是否是最好的方法,但我想到的是一个可变光标。你可以用电脑来做。您可以构建一个包含查询的函数,并返回ref curosr。在所有过程中,都可以调用该函数。这将节省您在每个过程中编写150多行查询的时间。更重要的是,它将您的程序限制为查询的一个副本,因此易于维护

返回ref游标的函数可以是这样的:

CREATE OR REPLACE FUNCTION my_ugly_query() 
                           RETURN SYS_REFCURSOR
AS
  my_cursor_ref SYS_REFCURSOR;
BEGIN
  OPEN my_cursor_ref FOR
       SELECT -- 150+ lines of query;
  RETURN my_cursor_ref;
END;
以下是如何使用它:

CREATE OR REPLACE PACKAGE BODY MyPackage
as
PROCEDURE PopulateTable
IS 
  l_cur_refcur   SYS_REFCURSOR;
  s_array        fetch_array;
BEGIN
  l_cur_refcur := my_ugly_query();

  LOOP
    FETCH tran_cursor BULK COLLECT INTO s_array;
    EXIT when s_array%NOTFOUND;
    FORALL counter in 1..s_array.COUNT
        INSERT INTO my_table VALUES s_array(counter);
  END LOOP;  

  CLOSE my_cursor;
  COMMIT;

END PopulateTable;
END MyPackage;

我不确定这是否是最好的方法,但我想到的是一个可变光标。你可以用电脑来做。您可以构建一个包含查询的函数,并返回ref curosr。在所有过程中,都可以调用该函数。这将节省您在每个过程中编写150多行查询的时间。更重要的是,它将您的程序限制为查询的一个副本,因此易于维护

返回ref游标的函数可以是这样的:

CREATE OR REPLACE FUNCTION my_ugly_query() 
                           RETURN SYS_REFCURSOR
AS
  my_cursor_ref SYS_REFCURSOR;
BEGIN
  OPEN my_cursor_ref FOR
       SELECT -- 150+ lines of query;
  RETURN my_cursor_ref;
END;
以下是如何使用它:

CREATE OR REPLACE PACKAGE BODY MyPackage
as
PROCEDURE PopulateTable
IS 
  l_cur_refcur   SYS_REFCURSOR;
  s_array        fetch_array;
BEGIN
  l_cur_refcur := my_ugly_query();

  LOOP
    FETCH tran_cursor BULK COLLECT INTO s_array;
    EXIT when s_array%NOTFOUND;
    FORALL counter in 1..s_array.COUNT
        INSERT INTO my_table VALUES s_array(counter);
  END LOOP;  

  CLOSE my_cursor;
  COMMIT;

END PopulateTable;
END MyPackage;

在包规范而不是包体中创建光标。然后,您可以使用package_name.cursor_name从任何包过程/函数中引用它

在包规范而不是包体中创建光标。然后,您可以使用package\u name.cursor\u name从任何包过程/函数中引用它

您的视图想法听起来不错,尽管
批量收集
forall
的效率并不比普通SQL低多少。如果卷很大,也许应该考虑使用
limit
子句。虽然
bulk collect
forall
的效率并不比普通SQL低多少,但您的视图想法听起来不错。如果数量很大,也许应该考虑一个
限制
条款。