Я пытаюсь объединить сгустки в цикле PL / SQL, и он возвращает нулевое значение, в то время как при использовании DBMS_OUTPUT выводит значения цикла, а при выполнении каждого результата сгустков также выводится.
Система предназначена для выполнения уже сохраненного SQL в таблице на основе имени отчета, переданного в нее.Этот конкретный отчет имеет много названий отчетов;отсюда конкатенация каждого из отчетов.Передаваемыми аргументами являются имя отчета, версия отчета, в которой вы заинтересованы, тип разделителя, который вы хотите, и список аргументов для неизвестных в SQL, если таковые имеются.Есть также два основных типа SQL;1, которому необходимо заменить имя_таблицы на временное имя_таблицы, а другое, которому требуется идентификатор, добавляется к имени_таблицы в SQL.
, пожалуйста, найдите ниже код для функции REPREF1.
CREATE OR REPLACE FUNCTION REPREF1(P_VER IN VARCHAR2 DEFAULT 'LATEST',
P_SEPARATOR IN VARCHAR2 DEFAULT ', ',
P_ARGLIST IN VAR DEFAULT NULL) RETURN CLOB IS
L_CLOB CLOB;
FUNCTION GET_CLOB(P_REPNAM IN VARCHAR2,
P_VER IN VARCHAR2 DEFAULT 'LATEST',
P_SEPARATOR IN VARCHAR2 DEFAULT ', ',
P_ARGLIST IN VAR DEFAULT NULL) RETURN CLOB IS
---------------------------------------------------------------------------------
-- TITLE - GET_CLOB beta - b.0 DATE 2010Mar12
--
-- DESCRIPTION - A function that return a report based on the report name put in
--
-- USAGE - select get_clob(p_repnam,p_ver, p_separator, var(varay(val_1,...val_n), varay(val_1,...val_n))) FROM dual
-----------------------------------------------------------------------------------------------------------------------------
V_SQL VARCHAR2(32767);
L_RESULT CLOB;
V_TITLE VARCHAR2(4000);
V_REPDATE VARCHAR2(30);
V_CNT NUMBER(2);
V_NUMARG NUMBER(3);
V_CDCRU NUMBER(3);
V_BCNT NUMBER(3);
V_NEWTABDAT VARCHAR2(30);
V_NEWTABLIN VARCHAR2(30);
L_COLLIST VARAY;
V_VER VARCHAR2(6);
N PLS_INTEGER;
V_CNTTAB NUMBER(3);
-- EXEC_SQL_CLOB
FUNCTION EXEC_SQL_CLOB(P_SQL IN VARCHAR2,
P_NUMARG IN NUMBER,
P_COLLIST IN VARAY DEFAULT NULL,
P_ARGLIST IN VARAY DEFAULT NULL,
P_SEPARATOR IN VARCHAR2 DEFAULT '') RETURN CLOB IS
------------------------------------------------------------------------------------------------------
-- TITLE - EXEC_SQL_CLOB beta - b.0 DATE 2010Mar22
--
-- DESCRIPTION - A function that returns a clob value after executing the sql query that is passed into it
--
-- USAGE - select exec_sql_clob(p_sql, p_numarg, var(varay(val_1, val_2,...val_n), varay(val_1, val_2,...val_n))) FROM dual
---------------------------------------------------------------------------------------------------------------
L_CUR INTEGER DEFAULT DBMS_SQL.OPEN_CURSOR;
L_STATUS INTEGER;
V_COL VARCHAR2(4000);
L_RESULT CLOB;
L_COLCNT NUMBER DEFAULT 0;
L_SEPARATOR VARCHAR2(10) DEFAULT '';
V_NUMARG NUMBER(3);
BEGIN
-- parse the query for the report
DBMS_SQL.PARSE(L_CUR, P_SQL, DBMS_SQL.NATIVE);
-- whilst it is not more than 255 per line
FOR I IN 1 .. 255
LOOP
BEGIN
-- define each column in the select list
DBMS_SQL.DEFINE_COLUMN(L_CUR, I, V_COL, 2000);
L_COLCNT := I;
EXCEPTION
WHEN OTHERS THEN
IF (SQLCODE = -1007) THEN
EXIT;
ELSE
RAISE;
END IF;
END;
END LOOP;
-- If query has no bind variables
IF (P_ARGLIST IS NULL) THEN
IF (P_NUMARG = 0) THEN
-- Execute the query in the cursor
L_STATUS := DBMS_SQL.EXECUTE(L_CUR);
LOOP
-- Exit loop when fetch is complete
EXIT WHEN(DBMS_SQL.FETCH_ROWS(L_CUR) <= 0);
L_SEPARATOR := '';
FOR I IN 1 .. L_COLCNT
LOOP
DBMS_SQL.COLUMN_VALUE(L_CUR, I, V_COL);
L_RESULT := L_RESULT || L_SEPARATOR || V_COL;
L_RESULT := REPLACE(REPLACE(L_RESULT, CHR(13) || CHR(10), ' '), CHR(10), ' ');
L_SEPARATOR := P_SEPARATOR;
END LOOP;
L_RESULT := L_RESULT || CHR(13);
END LOOP;
ELSE
RAISE_APPLICATION_ERROR(-20011, ' INCORRECT NUMBER OF ARGUMENTS PASSED IN LIST ');
END IF;
-- Query has bind variables
ELSE
-- Check if the numarg passed is the same has stored in the table
SELECT NUMARG
INTO V_NUMARG
FROM REPVER
WHERE REPCODE = P_SQL;
-- If number of arguments is greater than 0
IF (V_NUMARG > 0) THEN
-- Check if the number of arguments are the same
IF (P_NUMARG = V_NUMARG) THEN
-- Replace the bind variables in the query
FOR J IN 1 .. P_ARGLIST.COUNT
LOOP
DBMS_SQL.BIND_VARIABLE(L_CUR, P_COLLIST(J), P_ARGLIST(J));
END LOOP;
-- Execute the query in the cursor
L_STATUS := DBMS_SQL.EXECUTE(L_CUR);
LOOP
-- Exit loop when fetch is complete
EXIT WHEN(DBMS_SQL.FETCH_ROWS(L_CUR) <= 0);
L_SEPARATOR := '';
FOR I IN 1 .. L_COLCNT
LOOP
DBMS_SQL.COLUMN_VALUE(L_CUR, I, V_COL);
L_RESULT := L_RESULT || L_SEPARATOR || V_COL;
L_RESULT := REPLACE(REPLACE(L_RESULT, CHR(13) || CHR(10), ' '), CHR(10), ' ');
L_SEPARATOR := P_SEPARATOR;
END LOOP;
L_RESULT := L_RESULT || CHR(13);
END LOOP;
ELSE
RAISE_APPLICATION_ERROR(-20011, ' INCORRECT NUMBER OF ARGUMENTS PASSED IN LIST ');
END IF;
ELSE
-- If the number of argument is equal to 0
IF (P_NUMARG = 0) THEN
-- Execute the query in the cursor
L_STATUS := DBMS_SQL.EXECUTE(L_CUR);
LOOP
-- Exit loop when fetch is complete
EXIT WHEN(DBMS_SQL.FETCH_ROWS(L_CUR) <= 0);
L_SEPARATOR := '';
FOR I IN 1 .. L_COLCNT
LOOP
DBMS_SQL.COLUMN_VALUE(L_CUR, I, V_COL);
L_RESULT := L_RESULT || L_SEPARATOR || V_COL;
L_RESULT := REPLACE(REPLACE(L_RESULT, CHR(13) || CHR(10), ' '), CHR(10), ' ');
L_SEPARATOR := P_SEPARATOR;
END LOOP;
L_RESULT := L_RESULT || CHR(13);
END LOOP;
ELSE
RAISE_APPLICATION_ERROR(-20011, ' INCORRECT NUMBER OF ARGUMENTS PASSED IN LIST ');
END IF;
END IF;
END IF;
-- Close cursor
DBMS_SQL.CLOSE_CURSOR(L_CUR);
RETURN L_RESULT;
END EXEC_SQL_CLOB;
BEGIN
-- Check if the version entered is null or latest
IF (P_VER IS NULL)
OR (UPPER(P_VER) = UPPER('LATEST')) THEN
SELECT MAX(VER)
INTO V_VER
FROM REPORT B, REPVER R
WHERE UPPER(REPNAM) = UPPER(P_REPNAM)
AND B.REPREF = R.REPREF;
ELSE
V_VER := P_VER;
END IF;
-- Check if the repname and version entered exists
SELECT COUNT(*)
INTO V_CNT
FROM REPORT B, REPVER R
WHERE UPPER(REPNAM) = UPPER(P_REPNAM)
AND VER = V_VER
AND B.REPREF = R.REPREF;
IF (V_CNT > 0) THEN
-- Store the SQL statement, title and number of arguments of the report name passed.
SELECT REPCODE, REPTITLE, NUMARG, COLLIST
INTO V_SQL, V_TITLE, V_NUMARG, L_COLLIST
FROM REPVER R, REPORT B
WHERE UPPER(REPNAM) = UPPER(P_REPNAM)
AND B.REPREF = R.REPREF
AND VER = V_VER;
V_REPDATE := TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI');
L_RESULT := V_TITLE || ' (' || P_REPNAM || ' version ' || V_VER || ') generated ' || V_REPDATE || CHR(13) || CHR(13);
-- Check for some specific type of queries
SELECT COUNT(*)
INTO V_CDCRU
FROM REPVER R, REPORT B
WHERE CTDDATA = 'Y'
AND UPPER(REPNAM) = UPPER(P_REPNAM)
AND B.REPREF = R.REPREF
AND VER = V_VER;
SELECT COUNT(*)
INTO V_BCNT
FROM REPVER R, BODCREPS B
WHERE BENLIST = 'Y'
AND UPPER(REPNAM) = UPPER(P_REPNAM)
AND B.REPREF = R.REPREF
AND VER = V_VER;
IF (V_CDCRU > 0) THEN
V_NEWTABDATA := 'CT_' || 'DAT_' || P_ARGLIST(1) (P_ARGLIST(1).FIRST);
V_NEWTABLINK := 'CT_' || 'LIN_' || P_ARGLIST(1) (P_ARGLIST(1).FIRST);
-- Check if the tables exist
SELECT COUNT(*)
INTO V_CNTTAB
FROM ALL_TABLES
WHERE TABLE_NAME = V_NEWTABDAT
OR TABLE_NAME = V_NEWTABLIN
AND OWNER = 'SCOTT';
IF (V_CNTTAB > 0) THEN
V_SQL := UPPER(V_SQL);
V_SQL := REPLACE(V_SQL, 'CT_DAT_CRU', V_NEWTABDAT);
V_SQL := REPLACE(V_SQL, 'CT_LIN_CRU', V_NEWTABLIN);
ELSE
V_SQL := 'SELECT ''THE TABLE NOT CREATED YET''
FROM DUAL';
END IF;
END IF;
IF (V_BCNT > 0) THEN
V_SQL := UPPER(V_SQL);
V_SQL := REPLACE(V_SQL, 'LIST', P_ARGLIST(1) (P_ARGLIST(1).LAST));
END IF;
IF (P_ARGLIST IS NULL) THEN
-- execute the query
L_RESULT := L_RESULT || EXEC_SQL_CLOB(V_SQL, V_NUMARG, L_COLLIST, NULL, P_SEPARATOR);
ELSE
N := P_ARGLIST.COUNT;
-- execute the query
L_RESULT := L_RESULT || EXEC_SQL_CLOB(V_SQL, V_NUMARG, L_COLLIST, P_ARGLIST(N), P_SEPARATOR);
END IF;
RETURN L_RESULT;
ELSE
RAISE_APPLICATION_ERROR(-20012, P_REPNAM || ' or ' || P_VER || ' DOES NOT EXIST ');
END IF;
END GET_CLOB;
BEGIN
FOR I IN (SELECT REPNAM
FROM REPORT
WHERE REPREF NOT IN ('R01', 'R02', 'R03', 'R04'))
LOOP
SELECT CONCAT_CLOB(GET_CLOB(I.REPNAM, P_VER, P_SEPARATOR, P_ARGLIST))
INTO L_CLOB
FROM DUAL;
DBMS_OUTPUT.PUT_LINE(I.REPNAM);
-- DBMS_OUTPUT.PUT_LINE (COUNT(i.REPNAM));
END LOOP;
RETURN L_CLOB;
END REPREF1;
/
Cheers, Tunde
Большое спасибо APC за то, что код выглядел лучше.@ Роберт, последний цикл в коде возвращает ноль даже с помощью агрегатной функции CONCAT_CLOB, которая объединяет сгустки.
FOR I IN (SELECT REPNAM
FROM REPORT
WHERE REPREF NOT IN ('R01', 'R02', 'R03', 'R04'))
LOOP
SELECT CONCAT_CLOB(GET_CLOB(I.REPNAM, P_VER, P_SEPARATOR, P_ARGLIST))
INTO L_CLOB
FROM DUAL;
DBMS_OUTPUT.PUT_LINE(I.REPNAM);
END LOOP;
, когда я пытаюсь это сделать,
FOR I IN (SELECT REPNAM
FROM REPORT
WHERE REPREF NOT IN ('R01', 'R02', 'R03', 'R04'))
LOOP
L_CLOB := L_CLOB || CHR(13) || GET_CLOB(I.REPNAM, P_VER, P_SEPARATOR, P_ARGLIST);
DBMS_OUTPUT.PUT_LINE(I.REPNAM);
END LOOP;
Это также дает ноль;но на этот раз вывод дБмс для репнам не завершен.