【问题标题】:No result from a query stored in a VARCHAR2 variable is treated as an empty string or a NULL? - Oracle PL/SQL - Oracle 11g存储在 VARCHAR2 变量中的查询没有结果被视为空字符串或 NULL? - Oracle PL/SQL - Oracle 11g
【发布时间】:2021-01-25 20:53:45
【问题描述】:

我有一个执行 SELECT INTO 并将返回的结果存储在名为 account_ 的 VARCHAR2 变量中的过程:

SELECT DISTINCT NVL(XYZ_API.Get_Ref(company, currency, pay_type, order_id), 
                    XYZ_API.Get_Id(company, currency, pay_type, order_id)) account
INTO account_
FROM some_table
WHERE company                     = company_
     AND payment_type             = 'SUPP'
     AND order_id                 = order_id_
     AND payment_date             = pay_date_;

company_order_id_pay_date_ 都是我用来过滤记录的 VARCHAR2 变量。

取入account_ 的结果随后被格式化如下并存储在另一个名为giro_ 的VARCHAR2 变量中:

giro_ := LPAD( TRANSLATE( account_, '1234567890- ','1234567890' ), 16, '0' );

然后我检查giro_是否为数字,如下用FOR循环。

FOR i_ IN 1..LENGTH( giro_ ) LOOP
     c_ := ASCII( SUBSTR( giro_ , i_, 1 ) );
     IF ( c_ < ASCII( '0' ) OR c_ > ASCII( '9' ) ) THEN
        RETURN FALSE;
     END IF;
  END LOOP;

我有一个场景,上面显示的 SELECT 查询没有获取任何记录。

这最终会在 FOR 循环中引入异常,并出现 ORA-06502 和 ORA-06512 错误。

据我了解,原因是LENGTH( giro_ )

1..LENGTH( giro_ ) 失败,因为 giro_ 值的 LENGTH(LENGTH 为 NULL)无法转换为 NUMBER。

我的问题是,此时在这种情况下,giro_ 是空字符串还是 NULL? 这里到底发生了什么?

谢谢!

【问题讨论】:

  • 虽然我开始意识到空字符串和 NULL 在 Oracle 中是相同的,但LENGTH 是极少数缺点之一。如果是空字符串,它会返回 NULL 而不是零。奇怪的是,您看到了使用DISTINCT 的必要性,但看到它保证得到一个结果行。这可能表明数据模型不佳或查询不那么健壮。
  • 是的,我同意你的说法。我会尝试修改我的数据/查询 :) 感谢您的输入!

标签: oracle plsql oracle11g ora-06512 ora-06502


【解决方案1】:

你的理解是错误的。 LENGTH 总是会返回一个数字(字符串长度),它不会检查它的参数是否一个数字。

规则的例外是如果它的 (LENGTH's) 参数是一个空字符串(在 Oracle 中,它等于 NULL) - 那么长度也是 unknown (@ 987654324@):

SQL> select length(''), length(null) from dual;

LENGTH('') LENGTH(NULL)
---------- ------------


SQL>

在这种情况下,修改您的代码,使其包含NVL 函数,例如

FOR i_ IN 1 .. NVL(LENGTH( giro_ ), 0) LOOP

对于空字符串,它不会做任何事情。

【讨论】:

  • 您好,谢谢您的回答。我认为您同意我在问题中的观点?当我说“1..LENGTH(giro_) 失败,因为 giro_ 值的 LENGTH 不能转换为 NUMBER”时,我的意思是代码失败了,因为 LENGTH 的返回值在这里是 NULL。所以,循环不能从 1 到 NULL,它应该是 1 到某个数字。
  • 不客气。完全正确 :) 对不起,如果我误解了你的意思。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-12
  • 1970-01-01
  • 1970-01-01
  • 2011-02-02
  • 2023-03-11
相关资源
最近更新 更多