Отображать содержимое файла, разделенного символом разделителя
Я пытаюсь отобразить содержимое файла, разделенного символом разделителя. Точнее, начиная с этой темы, я пытаюсь отобразить результат как:
БББ
ааа
QQQ
ссс
но источник данных должен быть взят из файла.
До сих пор я пробовал:
DECLARE
l_bfile bfile;
BEGIN
l_bfile := bfilename(my_dir, my_file);
dbms_lob.fileopen(l_bfile);
FOR i IN
(SELECT TRIM(regexp_substr(TO_CHAR(l_bfile),'[^;]+',1,level) ) AS q
FROM dual
CONNECT BY regexp_substr(TO_CHAR(l_bfile),'[^;]+',1,level) IS NOT NULL
ORDER BY level
)
LOOP
dbms_output.put_line(i.q);
END LOOP;
EXCEPTION
WHEN No_Data_Found THEN
NULL;
END;
В результате я получил
PL/SQL: ORA-00932: несовместимые типы данных: ожидается, что NUMBER получил FILE
Кто-нибудь может дать мне подсказку, пожалуйста?
2 ответа
Нужно написать это как новый ответ, так как он слишком велик для комментария к @SmartDumb:
Имейте в виду, регулярное выражение формы '[^;]+'
(обычно используется для разбора списков с разделителями) завершается неудачно, когда в списке обнаруживаются элементы NULL. Пожалуйста, смотрите этот пост для получения дополнительной информации: /questions/36255452/razdelit-zapyatyie-znacheniya-v-stolbtsyi-v-oracle/36255467#36255467
Вместо этого, пожалуйста, используйте эту форму вызова regexp_substr (заметьте, я удалил второй элемент):
SELECT TRIM(regexp_substr('bbb;;qqq;ccc','(.*?)(;|$)',1,level, null, 1) ) AS q
FROM dual
CONNECT BY regexp_substr('bbb;;qqq;ccc','(.*?)(;|$)',1,level) IS NOT NULL
ORDER BY level
Это может быть или не быть важным в этом примере, это зависит от того, имеет ли порядок элемент в строке значение для вас или вам нужно сохранить значение NULL. т.е. если вам нужно знать, что второй элемент - NULL, тогда это будет работать.
PS Выполните поиск внешних таблиц и посмотрите, можете ли вы использовать это решение. Это позволит вам запросить файл, как если бы он был таблицей.
Вы можете попробовать это, если ваш файл содержит одну строку (отсюда и вопрос о файловой структуре):
DECLARE
utlFileHandle UTL_FILE.FILE_TYPE;
vLine varchar2(100);
BEGIN
utlFileHande := UTL_FILE.FOPEN(my_dir, my_file, 'r');
utl_file.get_line(utlFileHande, vLine);
FOR i IN
(SELECT TRIM(regexp_substr(vLine,'[^;]+',1,level) ) AS q
FROM dual
CONNECT BY regexp_substr(vLine,'[^;]+',1,level) IS NOT NULL
ORDER BY level
)
LOOP
dbms_output.put_line(i.q);
END LOOP;
utl_file.fclose(utlFileHande);
EXCEPTION
WHEN No_Data_Found THEN
utl_file.fclose(utlFileHande);
null;
END;