0

我正在尝试使用在 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: 无效号码。

有没有更好的方法来做到这一点甚至可能?

4

2 回答 2

4

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

尝试将字符串转换为数字失败,因为字符串不是有效的数字文字。在算术函数或表达式中只能使用数字字段或包含数字数据的字符字段。只有数字字段可以添加到日期或从日期中减去。

http://ora-01722.ora-code.com/

更新#1:

你的描述让我担心:

我正在尝试使用在 IN 子句中返回逗号分隔字符串的子查询。

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

更新#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

因为您无法将 number1与 string进行比较'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
于 2011-01-19T16:04:09.553 回答
2

至少,为了引用 alias GROUP_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) 

如果表中的PERSON_IDSOTHER是逗号分隔的值列表,则您的 IN 列表不会像您期望的那样。您需要将标量字符串(其中恰好有逗号)转换为多个 PERSON_ID 值的某种集合。有多种方法可以做到这一点,Tom Kyte 有一个使用变量 IN list的示例。假设您复制 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) 
于 2011-01-19T16:13:29.090 回答