添加存储为varchar的十进制值时出现问题

时间:2019-06-10 05:21:25

标签: sql oracle plsql

我有一个临时表,其中有两个数量列,创建为varchar2类型,以允许从excel导入。稍后,对这些字段进行验证,以确保它们包含数值数据,并且在对实际表进行更新之前,每行的值总和应大于零。

我具有验证列是否包含任何非数字数据的功能,该功能可以按预期工作。

   FUNCTION f_isnumber (pin_string IN VARCHAR2)
      RETURN INT
   IS
      v_new_num   NUMBER;
   BEGIN
      IF TRIM (pin_string) IS NOT NULL
      THEN
         v_new_num := TO_NUMBER (pin_string);


         RETURN 1;
      END IF;

      RETURN 0;
   EXCEPTION
      WHEN VALUE_ERROR
      THEN
         RETURN 0;
   END f_isnumber;

接下来,我要列出所有两个金额字段的值为零的行。在下面的查询中,我只选择两列的总和。

WITH CTE1
     AS (SELECT TO_NUMBER (PURCH_AMT) + TO_NUMBER (SELL_AMT) AS Total, ROW_ID
           FROM STG_MAINTENANCE
          WHERE     PKG_MAINTENANCE.f_isnumber (PURCH_AMT) > 0
                AND PKG_MAINTENANCE.f_isnumber (SELL_AMT) > 0)
SELECT TO_NUMBER (Total), CTE1.*
  FROM CTE1

但是,一旦我添加where子句,查询就会失败,并显示错误“ ORA-01722:无效编号”

WITH CTE1
     AS (SELECT TO_NUMBER (PURCH_AMT) + TO_NUMBER (SELL_AMT) AS Total, ROW_ID
           FROM STG_MAINTENANCE
          WHERE     PKG_MAINTENANCE.f_isnumber (PURCH_AMT) > 0
                AND PKG_MAINTENANCE.f_isnumber (SELL_AMT) > 0)
SELECT TO_NUMBER (Total), CTE1.*
  FROM CTE1
 WHERE Total = 0

表包含有效数字,空格和有效小数,零等。我希望内部where子句将消除所有非数字值,并且我只会获得有效的十进制值,并且如果用户已导入0或0.00 但是出现无效数字错误。

样本数据:

Create table STG_MAINTENANCE (ROW_ID INT, PURCH_AMT VARCHAR2(500), SELL_AMT VARCHAR2(500));

INSERT INTO STG_MAINTENANCE values(1, 'A','4.5');
INSERT INTO STG_MAINTENANCE values(2, '0','0.0');
INSERT INTO STG_MAINTENANCE values(3, '5.5','4.5');
INSERT INTO STG_MAINTENANCE values(4, '','4.5');
INSERT INTO STG_MAINTENANCE values(5, 'B','C');
INSERT INTO STG_MAINTENANCE values(6, '','');

1 个答案:

答案 0 :(得分:0)

我认为Oracle处理查询的方式会导致查询错误。

例如,您可以使用MATERIALIZE提示并按如下所示编写查询:

WITH CTE1 AS (
    SELECT /*+MATERIALIZE*/
        TO_NUMBER(PURCH_AMT) + TO_NUMBER(SELL_AMT) AS TOTAL,
        ROW_ID
    FROM
        STG_MAINTENANCE
    WHERE
        PKG_MAINTENANCE.F_ISNUMBER(PURCH_AMT) > 0
        AND PKG_MAINTENANCE.F_ISNUMBER(SELL_AMT) > 0
)
SELECT
    TO_NUMBER(TOTAL),
    CTE1.*
FROM
    CTE1
WHERE
    TOTAL = 0

您可以从oracle文档中进一步了解MATERIALIZE提示。

希望这对您有帮助。