我有:
分隔的列1:2:3:
。我想把它变成1,2,3
。我的查询看起来像,
select name
from status where id IN (SELECT REPLACE(NEXT_LIST,':',',')
FROM status);
但我收到了错误
ORA-01722:无效号码
答案 0 :(得分:2)
(1, 2, 3, 4)
与('1, 2, 3, 4')
不同。 IN
需要前者,一系列价值观;你给它后者,一个字符串。
您主要有两种选择:
更新选项#3:在':1:2:3:4:' like '%:3:%'
中使用LIKE
(这要求你的next_list只包含用冒号分隔的简单数字。没有前导零,没有空格,没有其他字符。)
select name
from status
where (select ':' || next_list || ':' from status) like '%:' || id || ':%'
答案 1 :(得分:1)
我同意Thorsten,但我想知道我们是否只需再更换一次它会起作用吗?我的意思是这样的:
select name
from status where id IN (SELECT replace(REPLACE(NEXT_LIST,':',','),'''','')
FROM status);
答案 2 :(得分:0)
REPLACE
函数返回一个字符串,因此嵌套查询返回一个字符串值列表(其中冒号用逗号替换),但不返回数字值列表。当Oracle引擎解释id IN (str_value)
时,它会尝试将str_value
强制转换为数字并引发异常ORA-01722: invalid number
,因为有些情况类似于'1:2:3',这些情况是可定义的不可解析的。
“纯sql”方法使我们使用自定义函数检测数字是否在以冒号分隔的列表中:
-- you need Oracle 12c to use function in the WITH clause
-- on earlier versions just unwrap CASE statement and put it into query
WITH
FUNCTION in_list(p_id NUMBER, p_list VARCHAR2) RETURN NUMBER DETERMINISTIC IS
BEGIN
RETURN CASE WHEN
instr(':' || p_list || ':', ':' || p_id || ':') > 0
THEN 1 ELSE 0 END;
END;
SELECT *
FROM status
WHERE in_list(id, next_list) = 1;
这里我假设next_list
列中的值是包含用冒号分隔的数字的字符串,没有空格。在通常情况下,您应修改函数以匹配特定的列表格式。