PL SQL-动态表引用和光标问题

时间:2018-07-11 13:42:14

标签: sql loops dynamic plsql cursor

谢谢。

我有一个过程将数据库表名作为输入,遍历数据库表并将表写入平面文件。

我正在努力使用Dynamic SQL生成一个游标,该游标遍历动态选择的表。

使用ref游标不起作用,因为我无法使用:

unld_record v_unldTable%ROWTYPE;

在声明中作为v_unldTable是尚未填充的变量。这意味着稍后游标会下降,因为我们无法获取具有适当类型的变量(ROWTYPE与v_unldTable变量中引用的表相同)。我还认为,我需要在DBMS_SQL的基础上使用一些东西,以便将逻辑公式化,因为v_unldTable将传递文字字符串v_unldTable而不是其值的数据库表名称。

请参见下面的代码:

create or replace PROCEDURE UNLD_TO_HDL (processComponent IN VARCHAR2)
IS
    fHandle UTL_FILE.FILE_TYPE;
    concatData VARCHAR2(240);
    concatHDLMetaTags VARCHAR2(240);
    outputFileName VARCHAR2(240);
    TYPE rowArrayType IS TABLE OF VARCHAR2(240);
    rowArray rowArrayType;
    emptyArray rowArrayType;
    valExtractArray rowArrayType;
    hdlFileName VARCHAR2(240);
    v_unldTable VARCHAR2(240);
    countUNLDRows Number;
    dataType VARCHAR2(240);
    current_table VARCHAR2(30);
    value_to_char VARCHAR2(240);

    TYPE EmpCurTyp IS REF CURSOR;   
    v_emp_cursor EmpCurTyp; 
    --******************************************************
    unld_record v_unldTable%ROWTYPE;
    --******************************************************
    v_stmt_str VARCHAR2(240);

BEGIN 
    SELECT HDL_FILE_NAME
    INTO hdlFileName
    FROM GNC_HDL_CREATION_PARAMS
    WHERE PROCESS_COMPONENT = processComponent;

    SELECT UNLD_TABLE
    INTO v_unldTable
    FROM GNC_HDL_CREATION_PARAMS
    WHERE PROCESS_COMPONENT = processComponent
    FETCH NEXT 1 ROWS ONLY;

    v_stmt_str := ('SELECT * FROM ' || v_unldTable);

    SELECT OBJECT_NAME 
    INTO current_table 
    FROM USER_OBJECTS 
    WHERE OBJECT_NAME = v_unldTable AND OBJECT_TYPE = 'TABLE';

    SELECT LISTAGG(HDL_META_TAG,'|')
    WITHIN GROUP(ORDER BY HDL_META_TAG)
    INTO concatHDLMetaTags
    FROM GNC_MIG_CONTROL
    WHERE HDL_COMP = processComponent;

    SELECT DB_FIELD
    BULK COLLECT INTO valExtractArray
    FROM GNC_MIG_CONTROL
    WHERE HDL_COMP = processComponent AND ACTIVE_FLAG = 'Y'
    ORDER BY HDL_META_TAG;

    fHandle := UTL_FILE.FOPEN('./', hdlFileName, 'W');
    UTL_FILE.PUTF(fHandle, concatHDLMetaTags + '\n');

    SELECT num_rows INTO countUNLDRows FROM user_tables where table_name = 
    v_unldTable;

    OPEN v_emp_cursor FOR v_stmt_str;
    LOOP
    FETCH v_emp_cursor INTO unld_record;
    EXIT WHEN v_emp_cursor%NOTFOUND;
        rowArray := NULL;
        FOR value in 1..valExtractArray.COUNT LOOP
            rowArray.extend();

            SELECT data_type 
            INTO dataType 
            FROM all_tab_columns 
            WHERE table_name = 'GNC_UNLD_BANK' AND column_name = 
            valExtractArray(value);

            IF dataType = 'VARCHAR2' THEN BEGIN 
                SELECT valExtractArray(value) INTO value_to_char FROM 
                unld_record;
            END;
            ELSIF dataType = 'DATE' THEN BEGIN 
                SELECT TO_CHAR(valExtractArray(value),'YYYY/MM/DD') INTO 
                value_to_char FROM unld_record;
            END;
            ELSIF dataType = 'NUMBER' THEN BEGIN 
                SELECT TO_CHAR(valExtractArray(value)) INTO value_to_char 
                FROM unld_record;
            END;
            END IF;

            rowArray(value) := value_to_char;

        END LOOP;
        concatData := NULL;
        FOR item in 1..rowArray.COUNT LOOP
            IF item = rowArray.COUNT THEN concatData := 
            (COALESCE(concatData,'') || rowArray(item));
            ELSE concatData := (COALESCE(concatData,'') || rowArray(item) || 
            '|');
            END IF;
        END LOOP;
        UTL_FILE.PUTF(fHandle, concatData + '/n');
    END LOOP;
    UTL_FILE.FCLOSE(fHandle);
 END;

0 个答案:

没有答案
相关问题