【问题标题】:Can't seem to find record by simple ID query似乎无法通过简单的 ID 查询找到记录
【发布时间】:2012-05-24 08:01:42
【问题描述】:

我有一些表格的视图:

SELECT UM00200M.ACCOUNT_NO AS INDEX1,
          CONCAT (CONCAT (TRIM (UM00200M.PERSON_LNM), ' '),
                  TRIM (UM00200M.PERSON_FNM))
             AS INDEX2,
          DECODE (NVL (TRIM (SG00100M.PERSON_ID_CUSTOM), 0),
                  0, UM00200M.PERSON_NO,
                  SG00100M.PERSON_ID_CUSTOM)
             INDEX3,
          NULL AS INDEX4,
          'CONS_ACCTG' AS GROUPNAME
     FROM UM00200M, SG00100M
    WHERE UM00200M.PERSON_NO = SG00100M.PERSON_NO

这给了我(抱歉格式化):

Column_Name DATA_TYPE NULLABLE COLUMNT_ID COMMENTS INSERTABLE UPDATEABLE INDEX1 NUMBER(14,0) 否 1 是 是 是 INDEX2 VARCHAR2(81) 是 2 否 否 否 索引 3 编号 是 3 否 否 否 INDEX4 VARCHAR2(0) 是 4 否 否 否 GROUPNAME CHAR(10) 是 5 否 否 否

我正在查找所有具有 INDEX3 = 524118914 的记录

--Looking for INDEX3 = 524118914

--Fails:  01722. 00000 -  "invalid number"
Select *
from Cayenta.CAHeader 
where INDEX3 = 524118914;

--Fails:  01722. 00000 -  "invalid number"
Select *
from Cayenta.CAHeader 
where INDEX3 > 524118000 and INDEX3 < 524118999;

--Works
Select *
from Cayenta.CAHeader 
where INDEX3 > 524118000 and INDEX3 < 524999999; 

--Fails: 01722. 00000 -  "invalid number"
Select *
from Cayenta.CAHeader 
where INDEX3 > 524118000 and INDEX3 < 524999999 
ORDER BY INDEX3;

执行查询时,我没有得到预期的结果。为什么我会收到“无效号码”?

我认为这与 DECODE 函数有关,SG00100M.PERSON_ID_CUSTOM 是一个 CHAR(15 BYTE) 字段,但填充了所有数字数据。 (我知道 - 糟糕的设计,但它是第 3 方产品。)

感谢任何人提供的任何见解。

【问题讨论】:

    标签: sql oracle oracle10g


    【解决方案1】:

    这里发生的是隐式转换。这意味着在 where 子句的条件中,您将列 INDEX3 与一个数字进行比较。

    INDEX3 是一个 CHAR 列,因此 Oracle 文档的以下摘录适用于隐式转换:

    在算术运算和字符之间的比较期间 非字符数据类型,Oracle 将任何字符数据类型转换为 一个数字、日期或 rowid,视情况而定

    这意味着 INDEX3 中的所有值都将转换为 NUMBER,以便与您在示例中给出的数字进行比较。

    解决这个问题的简单方法是在数字周围使用引号并将其视为字符串。

    where INDEX3 = '524118914'
    

    这适用于相等条件,但可能不适用于使用 >= 和

    如果您认为这应该是一个数字字段,那么其中至少有一行包含非数字数据。要追踪这一点,您可以尝试使用以下条件检查数据:

    where regexp_like(INDEX3, '[^[:digit:]]')
    

    这仅检查数字(不是小数点等),因此您可能需要根据您的要求对其进行调整。

    我有点困惑为什么数据库说该列是数字数据类型。这似乎与 DECODE 语句的评估方式有关,并且数据类型来自第一个结果参数,即使默认参数是 CHAR 类型。

    【讨论】:

    • 是的,这就是我开始追寻的路径,但是当我在视图中查看 Index3 上的 DataType 时,它​​是一个“NUMBER”。我们在搜索时也有数据输入的“前导零”问题,所以我希望保留查询数字,而不是文本。我相信那是因为 UM00200M.PERSON_NO 是数字。不过,感谢您的想法。
    • 是的,我写了这么长的答案,然后意识到我没有完全回答你的问题。来自关于 DECODE 的 Oracle 文档:“Oracle 自动将返回值转换为与第一个结果相同的数据类型”,因此您为什么要为 INDEX3 列获取该数据类型。
    【解决方案2】:

    在字符字段中存储数字总是很痛苦...

    请为视图尝试以下 SQL - 解码器检查 PERSON_ID_CUSTOM 是否有数字。如果是,则转换它,如果不是 - 它将被 NULL 替换:

        SELECT UM00200M.ACCOUNT_NO AS INDEX1,
                  CONCAT (CONCAT (TRIM (UM00200M.PERSON_LNM), ' '),
                          TRIM (UM00200M.PERSON_FNM))
                     AS INDEX2,
                  DECODE (NVL (TRIM (SG00100M.PERSON_ID_CUSTOM), 0),
                          0, UM00200M.PERSON_NO,
    decode((
      REPLACE(
       TRANSLATE(
        TRIM(SG00100M.PERSON_ID_CUSTOM),'0123456789','00000000000'
       ),'0' ,NULL
      )
     ),NULL,to_number(trim(SG00100M.PERSON_ID_CUSTOM)))
    ) INDEX3,
                  NULL AS INDEX4,
                  'CONS_ACCTG' AS GROUPNAME
             FROM UM00200M, SG00100M
            WHERE UM00200M.PERSON_NO = SG00100M.PERSON_NO
    

    【讨论】:

    • 是的。我讨厌不得不去供应商那里更新视图,因为与他们一起工作很痛苦。但是,我认为没有选择余地。查询视图的工具不具备可以使这个复杂的查询成为可能的配置能力。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多