Oracle ORA-01427: подзапрос с одной строкой возвращает более одной строки

#sql #database #oracle #plsql

#sql #База данных #Oracle #plsql

Вопрос:

Я хочу проанализировать CSV-файл и сохранить данные в таблице. Как я могу это сделать. Файл хранится в таблице в виде большого двоичного объекта. Это первая проблема. Во-вторых, Oracle Apex «сказал», что приведенный ниже код не работает, потому что подзапрос вернул более одной строки. Но я не вижу этого места, когда он возвращается более чем на один ряд. Если существует другой способ хранения данных из файла в таблице, вы можете предложить его. Большое спасибо.

 DECLARE  l_ln NUMBER;  l_col1 VARCHAR2(255);  l_col2 VARCHAR2(255);  l_col3 VARCHAR2(255);  l_col4 VARCHAR2(255);  l_col5 NUMBER;  l_col6 DATE;  l_col7 DATE;  l_col8 NUMBER;  l_col9 NUMBER;  l_col10 VARCHAR2(255);  l_min_ln NUMBER;  l_max_ln NUMBER; BEGIN  /* start and stop */  SELECT  MIN(line_number),  MAX(line_number)  INTO  l_min_ln,  l_max_ln  FROM  t_files f,  TABLE ( apex_data_parser.parse(p_content =gt; f.f_blob, p_file_name =gt; f.f_name) ) p  WHERE  f.file_id = :p5_file  AND line_number gt; 1; /* end */  FOR counter IN l_min_ln..l_max_ln LOOP  SELECT  ff,  mm  ll,  bd,  (  SELECT  id  FROM  country  WHERE  upper(name) LIKE upper('%'  || :country  || '%')  ) co,  dtn,  ind,  no,  np  INTO  l_col1,  l_col3,  l_col2,  l_col4,  l_col5,  l_col6,  l_col7,  l_col8,  l_col9  FROM  (  SELECT  line_number id_l,  col001 ff,  col002 mm,  col003 ll  col004 bd,  col005 co,  col006 dtn,  col007 ind,  col008 no,  col009 np,  col010 col  FROM  temp_files f,  TABLE ( apex_data_parser.parse(  p_content =gt; f.f_blob,   p_skip_rows =gt; counter - 1,  p_max_rows =gt; counter,  p_file_name =gt; f.f_name  ) ) p  WHERE  f.file_id = :p5_file  AND line_number = counter  ) temp_table  WHERE  id_l = counter;   IF l_col1 IS NOT NULL OR l_col2 IS NOT NULL OR l_col3 IS NOT NULL OR l_col4 IS NOT NULL OR l_col5 IS NOT NULL OR l_col6 IS  NOT NULL OR l_col7 IS NOT NULL OR l_col8 IS NOT NULL OR l_col9 IS NOT NULL OR l_col10 IS NOT NULL THEN  INSERT INTO tbn (  d1,  d2,  d3,  d4,  d5,  d6,  d7,  d8,  d9  ) VALUES (  l_col1,  l_col2,  l_col3,  to_date(l_col4),  l_col5,  to_date(l_col6),  to_date(l_col7),  l_col8 || l_col9,  to_date(sysdate)  );   COMMIT;  END IF;   END LOOP;  END;  

Комментарии:

1. Вместо этого ПРИСОЕДИНЯЙТЕСЬ.

2. Я бы заподозрил, что встроенный подзапрос для идентификатора страны: WHERE upper(name) LIKE upper('%'|| :country|| '%') не похоже, что он всегда будет давать 1 уникальный результат. Является ли :страна пустой в некоторых случаях?

3. Используйте вместо select max(id) || case when count(*) gt; 1 then 'DUPLICATED! '|| count(*) end ... этого подзапрос, который возвращает только одну строку, и вы можете увидеть, какой идентификатор вызывает проблемы.

4. Большое спасибо. Это работает

Ответ №1:

Почему бы не сделать что-то подобное в 1 утверждении:

 INSERT INTO tbn ( d1, d2, d3, d4, d5, d6, d7, d8, d9 )   select col001, col002, col003, to_date(col004), c.id,   to_date(col006), to_date(col007), col008||col009, sysdate  from TEMP_FILES f,  TABLE ( apex_data_parser.parse( p_content =gt; f.f_blob,   p_file_name =gt; f.f_name ) ) p,  COUNTRY c  WHERE f.file_id = :p5_file  and upper(c.name) LIKE upper('%' || col005 || '%')  and ( col001 is not null or col002 is not null or   col003 is not null or col004 is not null or  col005 is not null or col006 is not null or   col007 is not null or col008 is not null or  col009 is not null or col010 is not null);