Oracle子句中的数字无效

Oracle子句中的数字无效,oracle,where,toad,Oracle,Where,Toad,我正在努力让查询正常工作,我真的需要一些帮助。我们有一个内部应用程序,用于在我工作的地方构建小型web应用程序。它基本上是一个拖放GUI。内置了使用键访问查询字符串值的功能 我通过查询字符串将逗号分隔的值列表传递到页面中。然后,我尝试在查询中使用值列表作为in子句的一部分 我可以看到查询字符串中的值是正确的 订单=1,2,3 下面是查询的具体部分 这里的OrderNumber是它从查询字符串映射的位置 我试着在Toad中运行类似的查询,我想我已经发现了这个问题。它给出了一个无效的数字错误,我认为

我正在努力让查询正常工作,我真的需要一些帮助。我们有一个内部应用程序,用于在我工作的地方构建小型web应用程序。它基本上是一个拖放GUI。内置了使用键访问查询字符串值的功能

我通过查询字符串将逗号分隔的值列表传递到页面中。然后,我尝试在查询中使用值列表作为in子句的一部分

我可以看到查询字符串中的值是正确的

订单=1,2,3

下面是查询的具体部分

这里的OrderNumber是它从查询字符串映射的位置

我试着在Toad中运行类似的查询,我想我已经发现了这个问题。它给出了一个无效的数字错误,我认为它将查询字符串值用单引号括起来。我可以在Toad中的“1,2,3”中复制错误,并在“1,2,3”中添加OrderNumber

这就是我真正困惑的地方。以下是蟾蜍的作品。 订单号在'1','2','3'

所以我试着通过 从dual中选择替换'1,2,3',',',chr39 | |','| | chr39

我已经确认在蟾蜍中返回'1','2','3'。 但是,当我在Toad中运行以下命令时,仍然会出现一个无效的数字错误

和订单号替换为'1,2,3',',,chr39 | | |','| | chr39

我一直在为此绞尽脑汁,但我想不出来。在我看来,如果和OrderNumber在'1','2','3'中起作用,并替换'1,2,3',',',','chr39 | | |','chr39返回'1','2','3',那么和OrderNumber在替换'1,2,3',',','chr39 | | chr39'中应该起作用


如果您能在这方面提供任何帮助,我们将不胜感激。我知道其余的查询工作。这就是为什么我没有发布它。我一直在努力让这个IN子句起作用。

我认为需要构建的子句是:

AND OrderNumber IN (1,2,3)
数字列表。您测试的示例:

AND OrderNumber IN ('1','2','3')
之所以有效,是因为列表中的每个元素都发生了从VARCHAR2到数字的隐式转换

以下子句不起作用,因为无法对字符串“1,2,3”进行隐式转换。请注意,该子句只有一个字符串元素:

AND OrderNumber IN ('1,2,3')

执行替换时,您正在将单个字符串:1,2,3转换为单个字符串:1'、'2'、'3,并且此单个字符串不能隐式转换为数字。

您可以尝试以下查询吗

SELECT * FROM orders
WHERE orderno IN    
    (
    SELECT TRIM(REGEXP_SUBSTR(str, '[^,]+', 1, LEVEL)) str
    FROM ( SELECT '1,2,3,4' str FROM dual )
    CONNECT BY INSTR(str, ',', 1, LEVEL - 1) > 0
    )
内联查询将字符串拆分为不同的行。因此,在执行它时,您将得到以下结果

SELECT trim(regexp_substr(str, '[^,]+', 1, LEVEL)) str
    FROM ( SELECT '1,2,3,4' str FROM dual )
    CONNECT BY instr(str, ',', 1, LEVEL - 1) > 0

1
2
3
4

现在,将这个结果传递给主查询IN子句应该可以了。

对拼音人的答案进行更改,允许列表中出现空元素。用于分析分隔列表的“[^,]+”正则表达式格式不处理空列表元素,如果存在空列表元素,则将返回错误的值,因此应避免使用该格式。例如,通过删除数字2来更改原始值,并查看结果。你将在第二个元素的位置得到一个“3”!下面是一种处理NULL并为元素返回正确值的方法:

SELECT TRIM(REGEXP_SUBSTR(str, '(.*?)(,|$)', 1, LEVEL, NULL, 1)) str
    FROM ( SELECT '1,,3,4' str FROM dual )
    connect by level <= regexp_count(str, ',') + 1;

有关更多信息和证据,请参见此处:

我猜,当您在“1”、“2”、“3”中有和OrderNumber时,Oracle可以将每个字符串单独转换为一个数字以满足条件。但“1,2,3”字符串不能转换为数字,因此该操作失败。对我来说有道理。顺便说一句,听起来,你的内部应用非常容易受到SQL注入攻击。我希望它不会被公开。这就是为什么我在替换之前和之后添加了char39 | | | | | | | char39,以从开头和结尾添加缺少的单引号。不过,这似乎还不足以满足我的需要。@JoeBrewing但这只是在现有字符串中嵌入引号,而不是创建新字符串,除非您使用的是动态sql。我明白了。这是有道理的。谢谢你的澄清。我会试试这个。谢谢。我试过了,效果很好。谢谢你能详细说明一下它的作用吗?我最近一直在努力提高我的SQL技能,但我仍然没有我想要的那么强。谢谢!我想我永远不必担心使用空值,但很高兴看到有关它如何工作的信息。@Gary_W感谢您添加此项。管理空值真的很重要。@JoeBrewing-总是期待意外的发生!