#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)