注意:我已经看到很多解决方案,所有人都说我不能使用带有PL / SQL类型的SQL。我必须使用CREATE或REPLACE,但我的限制是我无法使用系统对象执行此任务。
我在下面的例子中尝试过的只返回最后一行。
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-
答案 0 :(得分:1)
鉴于您无法在数据库中创建对象,我能想到的唯一解决方案是使用动态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文本,尽管这会带来挑战。
祝你好运。
答案 1 :(得分:0)
为了引用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;