Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将oracle PL/SQL集合中的所有行选择到SYS\u REFCURSOR中_Sql_Oracle_Plsql - Fatal编程技术网

如何将oracle PL/SQL集合中的所有行选择到SYS\u REFCURSOR中

如何将oracle PL/SQL集合中的所有行选择到SYS\u REFCURSOR中,sql,oracle,plsql,Sql,Oracle,Plsql,注意:我见过很多解决方案,都说我不能使用PL/SQL类型的SQL。我必须使用“创建”或“替换”,但我的限制是无法使用系统对象执行此任务 下面的示例只返回最后一行 create or replace PROCEDURE SP_TEST (TEST_cursor OUT SYS_REFCURSOR)IS TYPE TEMP_RECORD IS RECORD( entries NUMBER, name VA

注意:我见过很多解决方案,都说我不能使用PL/SQL类型的SQL。我必须使用“创建”或“替换”,但我的限制是无法使用系统对象执行此任务

下面的示例只返回最后一行

create or replace PROCEDURE SP_TEST (TEST_cursor OUT SYS_REFCURSOR)IS
 TYPE TEMP_RECORD IS RECORD(
                    entries   NUMBER,
                    name      VARCHAR2(50),
                    update    VARCHAR2(200)
                );
TYPE TEMP_TABLE IS TABLE OF TEMP_RECORD INDEX BY PLS_INTEGER;
VAR_TEMP       TEMP_TABLE;
IDX            PLS_INTEGER := 0;
BEGIN 
VAR_TEMP(IDX).cur_entries := 1;
VAR_TEMP(IDX).cur_entries := 2;
 OPEN TEST_cursor FOR
 SELECT VAR_TEMP(idx).cur_entries from dual;
END SP_TEST;
另一种方法尝试过

OPEN TEST_cursor FOR
  SELECT * FROM TABLE(VAR_TEMP)
--- It gives compilation error ora-

为了引用SQL中的类型(与PL/SQL相反),必须将它们创建为数据库中的对象。这实际上是一个范围问题:当您运行SQL时,您正在转移到不同的上下文。您在本地创建的任何结构在那里都不可用

CREATE TYPE temp_record AS OBJECT
(
    entries NUMBER,
    entry_name VARCHAR2 (50),
    update_value VARCHAR2 (200)
);

CREATE TYPE temp_table IS TABLE OF temp_record;

CREATE OR REPLACE PROCEDURE sp_test (test_cursor OUT SYS_REFCURSOR) IS
    var_temp temp_table := temp_table ();
BEGIN
    var_temp.EXTEND ();
    var_temp (var_temp.LAST).entries := 1;
    var_temp (var_temp.LAST).entry_name := 'test';

    OPEN test_cursor FOR SELECT * FROM TABLE (var_temp);
END sp_test;

鉴于无法在数据库中创建对象,我能想到的唯一解决方案是使用动态SQL:

CREATE TYPE temp_record AS OBJECT
(
    entries NUMBER,
    entry_name VARCHAR2 (50),
    update_value VARCHAR2 (200)
);

CREATE TYPE temp_table IS TABLE OF temp_record;

CREATE OR REPLACE PROCEDURE sp_test (test_cursor OUT SYS_REFCURSOR) IS
    var_temp temp_table := temp_table ();
    strSql  VARCHAR2(32767);
BEGIN
    -- Populate the temp table, or pass it in from elsewhere

    var_temp.EXTEND();
    var_temp (var_temp.LAST).entries := 1;
    var_temp (var_temp.LAST).entry_name := 'test';

    FOR i IN 1..var_temp.COUNT LOOP
      strSql := strSql ||
                  CASE
                    WHEN LENGTH(strSql) > 0 THEN ' UNION ALL '
                    ELSE NULL
                  END ||
                  'SELECT ' || var_temp.ENTRIES || ' ENTRIES,' ||
                            '''' || var_temp.ENTRY_NAME || ''' ENTRY_NAME FROM DUAL';
    END LOOP;

    OPEN test_cursor FOR strSql;
END sp_test;
现在,我可能把字符串连接逻辑弄乱了一点,但目标是最终得到一个SQL字符串,看起来像

SELECT 1 ENTRIES,'test' ENTRY_NAME FROM DUAL
UNION ALL
SELECT 2 ENTRIES,'test 2' ENTRY_NAME FROM DUAL
UNION ALL
SELECT 3 ENTRIES,'test_3' ENTRY_NAME FROM DUAL
但是,当然,没有漂亮的空白等等

动态SQL的32K限制最终可能会影响您,但如果遇到紧急情况,您可以使用DBMS_SQL包来处理任意大的SQL文本,尽管这也带来了它自己的挑战


祝你好运。

我已经提到,我无法在数据库级别创建此文件。寻找类似于是否有任何函数逻辑可以返回数组以便select可以工作的东西。1)过程是一个对象。2) 您无法从本地用户定义类型加载游标(按定义SQL)。让我进一步说明,需要用替代解决方案替换全局临时表,因为我们不希望管理这些依赖项。现在,如果我将从DB级别使用两个以上的对象,替代对象将创建更多的依赖项,而不是以前。如果经常调用此过程,可能需要小心,因为存在硬解析和相关的库缓存问题。感谢@Bob,我如何在同一示例中使用into,即选择条目,从某个表格中输入VAR_TEMP。请将其作为一个单独的问题写下来。谢谢