Oracle中in子句中返回的逗号分隔字符串的数目无效

Oracle中in子句中返回的逗号分隔字符串的数目无效,oracle,subquery,in-clause,ora-01722,Oracle,Subquery,In Clause,Ora 01722,我试图使用在in子句中返回逗号分隔字符串的子查询 方法如下: SELECT p.person_id, g.name || '>>' || p.firstname || ' ' || p.lastname as GROUP_PATH FROM PERSON p LEFT JOIN GROUP g ON ( g.group_id = p.group_id ) WHERE p.person_id IN ( SELECT person_ids FROM other WHE

我试图使用在in子句中返回逗号分隔字符串的子查询

方法如下:

SELECT p.person_id, g.name || '>>' || p.firstname || ' ' || p.lastname as GROUP_PATH
FROM PERSON p 
LEFT JOIN GROUP g ON (
    g.group_id = p.group_id
)
WHERE p.person_id IN ( 
    SELECT person_ids FROM other WHERE other_id = :OTHER_ID
) 
ORDER BY lower(GROUP_PATH) 
我得到了以下错误:

ORA-01722:无效号码


有没有更好的方法,甚至是可能的

最明显的解释是,你试图用一个字符串做数学题

试图转换的文件 将字符串转换为数字失败 因为字符串不是一个 有效的数字文字。只有数字 包含 数字数据可用于算术运算 函数或表达式。只有数字 字段可以加或减 从日期开始

更新#1:

你的描述让我担心:

我正在尝试使用一个子查询 返回以逗号分隔的字符串 在第条中

子查询不应返回逗号分隔的字符串(除非
g.group\u id
是字符串并且需要逗号分隔的字符串)。您必须根据需要检索尽可能多的行中的单个项(无论如何少于1000行)

更新#2:

我只想说清楚:

SELECT *
FROM (
    SELECT 1 AS FOO_ID FROM DUAL UNION SELECT 2 FROM DUAL UNION SELECT 3 FROM DUAL
) FOO;

FOO_ID                 
---------------------- 
1                      
2                      
3  
您可以这样做:

SELECT *
FROM (
    SELECT 1 AS FOO_ID FROM DUAL UNION SELECT 2 FROM DUAL UNION SELECT 3 FROM DUAL
) FOO
WHERE FOO_ID IN (1, 2);

FOO_ID                 
---------------------- 
1                      
2 
但不是这个:

SELECT *
FROM (
    SELECT 1 AS FOO_ID FROM DUAL UNION SELECT 2 FROM DUAL UNION SELECT 3 FROM DUAL
) FOO
WHERE FOO_ID IN ('1,2');

SQL Error: ORA-01722: invalid number
因为您无法将数字
1
与字符串
'1,2'
进行比较。子查询遵循类似的规则:

SELECT *
FROM (
    SELECT 1 AS FOO_ID FROM DUAL UNION SELECT 2 FROM DUAL UNION SELECT 3 FROM DUAL
) FOO
WHERE FOO_ID IN (
    SELECT 1 AS FOO_ID FROM DUAL UNION SELECT 2 FROM DUAL
);

FOO_ID                 
---------------------- 
1                      
2 

SELECT *
FROM (
    SELECT 1 AS FOO_ID FROM DUAL UNION SELECT 2 FROM DUAL UNION SELECT 3 FROM DUAL
) FOO
WHERE FOO_ID IN (
    SELECT '1,2' AS FOO_ID FROM DUAL
);

SQL Error: ORA-01722: invalid number

最明显的解释是你试图用一个字符串来做数学

试图转换的文件 将字符串转换为数字失败 因为字符串不是一个 有效的数字文字。只有数字 包含 数字数据可用于算术运算 函数或表达式。只有数字 字段可以加或减 从日期开始

更新#1:

你的描述让我担心:

我正在尝试使用一个子查询 返回以逗号分隔的字符串 在第条中

子查询不应返回逗号分隔的字符串(除非
g.group\u id
是字符串并且需要逗号分隔的字符串)。您必须根据需要检索尽可能多的行中的单个项(无论如何少于1000行)

更新#2:

我只想说清楚:

SELECT *
FROM (
    SELECT 1 AS FOO_ID FROM DUAL UNION SELECT 2 FROM DUAL UNION SELECT 3 FROM DUAL
) FOO;

FOO_ID                 
---------------------- 
1                      
2                      
3  
您可以这样做:

SELECT *
FROM (
    SELECT 1 AS FOO_ID FROM DUAL UNION SELECT 2 FROM DUAL UNION SELECT 3 FROM DUAL
) FOO
WHERE FOO_ID IN (1, 2);

FOO_ID                 
---------------------- 
1                      
2 
但不是这个:

SELECT *
FROM (
    SELECT 1 AS FOO_ID FROM DUAL UNION SELECT 2 FROM DUAL UNION SELECT 3 FROM DUAL
) FOO
WHERE FOO_ID IN ('1,2');

SQL Error: ORA-01722: invalid number
因为您无法将数字
1
与字符串
'1,2'
进行比较。子查询遵循类似的规则:

SELECT *
FROM (
    SELECT 1 AS FOO_ID FROM DUAL UNION SELECT 2 FROM DUAL UNION SELECT 3 FROM DUAL
) FOO
WHERE FOO_ID IN (
    SELECT 1 AS FOO_ID FROM DUAL UNION SELECT 2 FROM DUAL
);

FOO_ID                 
---------------------- 
1                      
2 

SELECT *
FROM (
    SELECT 1 AS FOO_ID FROM DUAL UNION SELECT 2 FROM DUAL UNION SELECT 3 FROM DUAL
) FOO
WHERE FOO_ID IN (
    SELECT '1,2' AS FOO_ID FROM DUAL
);

SQL Error: ORA-01722: invalid number

至少,为了引用别名
GROUP\u PATH
,在order BY子句中引用别名之前,需要使用定义别名的嵌套子查询。这实际上并没有导致ORA-01722错误,但这是一个问题

SELECT group_id, group_path
  FROM (SELECT g.group_id, 
               g.name || '>>' || p.firstname || ' ' || p.lastname as GROUP_PATH
          FROM PERSON p 
               LEFT JOIN GROUP g ON (
                      g.group_id = p.group_id
               )
         WHERE p.person_id IN ( 
               SELECT person_ids FROM other WHERE other_id = :OTHER_ID
               ) 
 ORDER BY lower(GROUP_PATH) 
如果
OTHER
表中的
PERSON\u id
列是一个以逗号分隔的值列表,则您的in列表将不会达到预期效果。您需要将标量字符串(其中碰巧有逗号)转换为某种多个人ID值的集合。有多种方法可以做到这一点,Tom Kyte举了一个使用。假设您复制Tom的IN_LIST函数,您应该能够执行以下操作

SELECT group_id, group_path
  FROM (SELECT g.group_id, 
               g.name || '>>' || p.firstname || ' ' || p.lastname as GROUP_PATH
          FROM PERSON p 
               LEFT JOIN GROUP g ON (
                      g.group_id = p.group_id
               )
         WHERE p.person_id IN ( 
               SELECT column_value
                 FROM TABLE(SELECT in_list(person_ids) 
                              FROM other 
                             WHERE other_id = :OTHER_ID)
               ) 
 ORDER BY lower(GROUP_PATH) 

至少,为了引用别名
GROUP\u PATH
,在order BY子句中引用别名之前,需要使用定义别名的嵌套子查询。这实际上并没有导致ORA-01722错误,但这是一个问题

SELECT group_id, group_path
  FROM (SELECT g.group_id, 
               g.name || '>>' || p.firstname || ' ' || p.lastname as GROUP_PATH
          FROM PERSON p 
               LEFT JOIN GROUP g ON (
                      g.group_id = p.group_id
               )
         WHERE p.person_id IN ( 
               SELECT person_ids FROM other WHERE other_id = :OTHER_ID
               ) 
 ORDER BY lower(GROUP_PATH) 
如果
OTHER
表中的
PERSON\u id
列是一个以逗号分隔的值列表,则您的in列表将不会达到预期效果。您需要将标量字符串(其中碰巧有逗号)转换为某种多个人ID值的集合。有多种方法可以做到这一点,Tom Kyte举了一个使用。假设您复制Tom的IN_LIST函数,您应该能够执行以下操作

SELECT group_id, group_path
  FROM (SELECT g.group_id, 
               g.name || '>>' || p.firstname || ' ' || p.lastname as GROUP_PATH
          FROM PERSON p 
               LEFT JOIN GROUP g ON (
                      g.group_id = p.group_id
               )
         WHERE p.person_id IN ( 
               SELECT column_value
                 FROM TABLE(SELECT in_list(person_ids) 
                              FROM other 
                             WHERE other_id = :OTHER_ID)
               ) 
 ORDER BY lower(GROUP_PATH) 

当我只查询子查询并将结果(逗号分隔)粘贴到IN子句中时,效果很好。有什么解释吗?假设你得到了
'10,20,30'
。你用它做什么
g.group\u id IN(10,20,30)
(三个数字)或
g.group\u id IN('10,20,30')
(一个字符串)?我注意到我重写了错误的查询。现在就去看看。我应该得到多个人ID,而不是团体ID。这并不重要;多个ID是否作为字符串返回?是的,我会这样说,因为person_id列的类型是varchar2。当我只查询子查询并将结果(以逗号分隔)粘贴到IN子句中时,效果很好。有什么解释吗?假设你得到了
'10,20,30'
。你用它做什么
g.group\u id IN(10,20,30)
(三个数字)或
g.group\u id IN('10,20,30')
(一个字符串)?我注意到我重写了错误的查询。现在就去看看。我应该得到多个人ID,而不是团体ID。这并不重要;多个id是否作为字符串返回?是的,我会这样说,因为列person_id的类型是varchar2。能否显示所有三个表的表定义(特别是id列类型);以及如何定义
:其他\u id
?您可能正在将一个数字列连接到一个您认为只有数字的varchar,或者只与数字匹配的varchar,并且它被一个您不希望相关的非数字值绊倒。我只是注意到我最初的查询是错误的。我更新了它。
person\u id
other
中是逗号分隔的列表吗?如果是这样,那在
in
子句中是行不通的。您需要将字符串解析为一个集合,并在查询中使用该集合。但是,您不应该首先在关系数据库中存储以逗号分隔的键列表,因此您可能希望修复数据模型;以及如何定义
:其他\u id
?你可能加入了一个c号码