无法在 varchar2() 中保存逗号分隔的数字字符串
Posted
技术标签:
【中文标题】无法在 varchar2() 中保存逗号分隔的数字字符串【英文标题】:Can't save comma separated number string in varchar2() 【发布时间】:2019-04-01 10:06:11 【问题描述】:我有一个我想通过单击添加的项目列表,为此我创建了一个表,其中包含一个类型为 varchar2(4000) 的列,在此列中我想列出引用其他表,因此我可以将此列的值粘贴为参数。前任。 select t.* from table_name t where t.point_id in (varchar2 string of comma separated point_ids)。
我遇到的问题是,当我在 varchar2 字段中输入超过 1 个 id 时,我得到 ORA-06502: PL/SQL: numeric or value error: character to number conversion error
如何避免此错误?我的字段是 varchar2,而不是数字,我不希望它被转换。我需要保存我正在解析的值。前任。 (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;
【问题讨论】:
该错误消息可能是件好事,因为将 CSV 数据存储在单个 SQL 列中通常不好。为什么要这样存储 CSV? 您确定该列的数据类型是 VARCHAR2 吗?请发布表的描述(在 SQL*Plus 中运行 DESC table_name 并将结果复制到此处 - 编辑问题,不要将其作为评论发布)。 我在尝试运行 desc 时收到无效的 SQL 语句。编辑:更新了我的桌子图片。 您能否在问题中发布插入语句的代码。 您不应该存储逗号分隔的值开始。规范化你的数据模型,你就没有这个问题 【参考方案1】:由于您没有给出示例,因此不确定我在这里可以为您提供什么帮助。看看下面的演示,也许xmltable
的结构可以解决你的问题。 HTH 韩币
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
【讨论】:
当我通过选择更新手动添加 id 时,我没有任何问题。但是当使用程序更新值时,我得到了错误。 "varchar2 string of comma separated point_ids" 是一个字符串。所以你的查询实际上是where 11 in ('11,12')
。因为您将数字与字符串进行比较,所以 Oracle 尝试将 '11,12'
转换为数字;它显然不是一个有效的数字,所以 Oracle 抛出 ORA-1722。您需要将字符串转换为一系列数字 ID。这就是 Peter 的 xmltable()
实现将解决您的问题的原因。
我的问题不是读取 id,而是更新 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)
【讨论】:
以上是关于无法在 varchar2() 中保存逗号分隔的数字字符串的主要内容,如果未能解决你的问题,请参考以下文章