Не удается сохранить числовую строку, разделенную запятыми, в varchar2()

#sql #oracle

#sql #Oracle

Вопрос:

У меня есть список элементов, которые я хочу добавить одним щелчком мыши, для этой цели я создал таблицу со столбцом с типом varchar2(4000), в этом столбце я хочу перечислить идентификаторы, которые ссылаются на другую таблицу, чтобы я мог вставить значение этого столбца в качестве параметра. например. выберите t.* из имя_таблицы t, где t.point_id в (строка varchar2, разделенная запятой point_ids).

Проблема, с которой я столкнулся, заключается в том, что когда я ввожу более 1 идентификатора в поле varchar2, я получаю ORA-06502: PL / SQL: ошибка числового значения: ошибка преобразования символа в число

Как я могу избежать этой ошибки? Мое поле — varchar2, а не number, и я не хочу, чтобы оно конвертировалось. Мне нужно, чтобы значение, которое я анализирую, было сохранено. например. (11, 12)

Изображение моей таблицы: введите описание изображения здесь

РЕДАКТИРОВАТЬ: Примечание — Мой выбор работает нормально, проблема, с которой я сталкиваюсь, связана с сохранением информации.

Моя вставка :

 procedure lab_water_pointsgroup (v_group_id lab_water_pointsgroups.group_name%type,
                          v_group_name lab_water_pointsgroups.group_code%type,
                          v_group_code lab_water_pointsgroups.lab_points_ids%type,
                          v_lab_points_ids lab_water_pointsgroups.group_id%type) as
begin
update lab_water_pointsgroups
   set group_name = v_group_name,
       group_code = v_group_code,
       lab_points_ids = v_lab_points_ids
 where  group_id = v_group_id;
if ( SQL%RowCount = 0 ) then
insert into lab_water_pointsgroups
  (group_id, group_name, group_code, lab_points_ids)
values
  (v_group_id, v_group_name, v_group_code, v_lab_points_ids);
end if;
end;
  

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

1. Это сообщение об ошибке, вероятно, хорошо, потому что обычно не хорошо хранить данные CSV в одном столбце SQL. Почему вы хотите сохранить CSV таким образом?

2. Вы уверены , что тип данных этого столбца — VARCHAR2? Пожалуйста, опубликуйте описание таблицы (запустите DESC table_name в SQL * Plus и скопируйте результат сюда — отредактируйте вопрос, не публикуйте его в качестве комментария).

3. Я получаю недопустимый оператор SQL при попытке запустить desc. Редактировать: обновлено изображением моей таблицы.

4. можете ли вы опубликовать свой код для инструкции insert в вопросе.

5. Для начала вам не следует хранить значения, разделенные запятыми. Нормализуйте свою модель данных, и у вас не возникнет этой проблемы

Ответ №1:

Не уверен, как именно я могу вам здесь помочь, поскольку вы не привели примера. Взгляните на приведенную ниже демонстрацию, возможно, конструкция с xmltable решит вашу проблему. HTH KR

 create table testtab (id number);
insert into  testtab values (1);

select * from testtab where id in ('1');   -- works
select * from testtab where id in (1);     -- works
select * from testtab where id in (1,2);   -- works
select * from testtab where id in ('1,2'); -- ORA-01722: invalid number
select * from testtab where id in (select to_number(xt.column_value) from xmltable('1,2') xt); -- works
  

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

1. Когда я добавляю идентификатор вручную, выбирая для обновления, у меня не возникает никаких проблем. Но при использовании процедуры для обновления значения я получаю ошибку.

2. «строка varchar2 с разделенными запятой идентификаторами точек» является строкой. Таким образом, ваш запрос эффективно where 11 in ('11,12') . Поскольку вы сравниваете число со строкой, Oracle пытается преобразовать '11,12' в число; это явно недопустимое число, поэтому Oracle выбрасывает ORA-1722. Вам нужно преобразовать строку в серию числовых идентификаторов. Вот почему xmltable() реализация Питера решит вашу проблему.

3. Моя проблема не в чтении идентификаторов, а в обновлении значения lab_point_ids.

Ответ №2:

Вот как вы определили параметры для своей процедуры:

 v_group_id        lab_water_pointsgroups.group_name%type,
v_group_name      lab_water_pointsgroups.group_code%type,
v_group_code      lab_water_pointsgroups.lab_points_ids%type,
v_lab_points_ids  lab_water_pointsgroups.group_id%type
  

Я подозреваю, что вы допустили ошибку с типами, потому что id имеет name тип, name имеет code тип и т.д. Так и должно быть:

 v_group_id        lab_water_pointsgroups.group_id%type,
v_group_name      lab_water_pointsgroups.group_name%type, 
v_group_code      lab_water_pointsgroups.group_code%type,
v_lab_points_ids  lab_water_pointsgroups.lab_points_ids%type
  

И я предлагаю использовать merge вместо этого update / insert , но это не то, что вы просили 🙂

Ответ №3:

Ваша ошибка заключается в том, что вы не делаете разницы между переменной, содержащей числа, разделенные запятыми, и фактическим перечислением в операторе ‘in’. После анализа вашего кода и подготовки к выполнению ваше утверждение будет выглядеть как .. id in ('1,2,3') вместо ..id in (1,2,3) , вы заметили разницу? Итак, вам нужно преобразовать значения, разделенные запятыми, в массив или, в данном случае, в коллекцию. Ваш код должен быть таким:

 select t.*
  from table_name t
 where t.point_id in
       (select regexp_substr(YOUR_VARCHAR2_COLUMN_VALUE, '[^,] ', 1, level)
          from dual
        connect by regexp_substr(YOUR_VARCHAR2_COLUMN_VALUE, '[^,] ', 1, level) is not null)