【发布时间】:2018-06-19 10:14:39
【问题描述】:
早上,
我正在尝试编写一个脚本,将卸载表(UNLD 到 HDL 文件)转换为使用 PLSQL 创建一个平面文件。我在尝试运行它时不断遇到语法错误,希望能得到专家的帮助!
以下是错误:
错误(53,21):PLS-00330:类型名称或子类型名称的使用无效
错误(57,32):PLS-00222:此范围内不存在名为“UNLDTABLE”的函数
我们的猜测是 unldTable 变量被视为字符串,而不是数据库表对象(在 PLSQL 中没有真正的经验)
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);
unldTable VARCHAR2(240);
countUNLDRows Number;
dataType VARCHAR2(240);
current_table VARCHAR2(30);
value_to_char VARCHAR2(240);
BEGIN
SELECT HDL_FILE_NAME
INTO hdlFileName
FROM GNC_HDL_CREATION_PARAMS
WHERE PROCESS_COMPONENT = processComponent;
SELECT UNLD_TABLE
INTO unldTable
FROM GNC_HDL_CREATION_PARAMS
WHERE PROCESS_COMPONENT = processComponent
FETCH NEXT 1 ROWS ONLY;
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
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 = unldTable;
FOR row in 1..countUNLDRows LOOP
rowArray := emptyArrayType;
FOR value in 1..valExtractArray.COUNT LOOP
rowArray.extend();
SELECT data_type INTO dataType FROM all_tab_columns where table_name = unldTable AND column_name = valExtractArray(value);
IF dataType = 'VARCHAR2' THEN (SELECT valExtractArray(value) INTO value_to_char FROM current_table WHERE ROWNUM = row);
ELSIF dataType = 'DATE' THEN (SELECT TO_CHAR(valExtractArray(value),'YYYY/MM/DD') INTO value_to_char FROM current_table WHERE ROWNUM = row);
ELSIF dataType = 'NUMBER' THEN (SELECT TO_CHAR(valExtractArray(value)) INTO value_to_char FROM current_table WHERE ROWNUM = row);
ENDIF;
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;
谢谢,
亚当
【问题讨论】:
-
我不确定这条线在做什么
rowArray(value) := unldTable(row).valExtractArray(value);。 unldTable 不是 Varchar2(240) 吗? -
我同意 Chrisrs2292;编译器抱怨是因为它应该抱怨。您正在使用带有字符串的数组语法。此外,您不需要为每个不同的变量声明不同的数组类型。 COALESCE(concatdata,concatdata)背后的意图是什么?
-
您好,感谢您的回答。 unldTable 包含一个 VARCHAR,它是我们感兴趣的表的名称。我已经更新了代码以尝试将其视为表而不是数组,但仍然没有运气。我在这里尝试做的是动态创建平面文件,我通过循环遍历表中的每一行并将该行中的每个值添加到数组来完成。在下一步中,我们将遍历并连接数组中的每个值并将其写入平面文件。
-
Coalesce 将 Null 替换为连接中的空字符串,抱歉更新了 PLSQL,因为它不正确。
-
你是对的,
unldTable被定义为一个字符串,因为你声明它为unldTable VARCHAR2(240);那是一个字符串。如果您希望它成为一个集合,只需使其成为您现有的集合类型之一(或者更好的是,定义一个字符串集合类型并将其重用于所有内容,而不是使用名称略有不同的三个相同类型)。