存储在VARCHAR2变量中的查询结果不会被视为空字符串或NULL?-Oracle PL/SQL-Oracle 11g

存储在VARCHAR2变量中的查询结果不会被视为空字符串或NULL?-Oracle PL/SQL-Oracle 11g,oracle,plsql,oracle11g,ora-06512,ora-06502,Oracle,Plsql,Oracle11g,Ora 06512,Ora 06502,我有一个执行SELECT INTO的过程,并将返回的结果存储在名为account\uu的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 WHE

我有一个执行SELECT INTO的过程,并将返回的结果存储在名为
account\uu
的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_;
公司
订单
付款日期
都是我用来过滤记录的VARCHAR2变量

然后将纳入
账户的结果格式化如下,并存储在另一个名为
giro\ucode>的VARCHAR2变量中:

giro:=LPAD(翻译(account_uu,'1234567890-','1234567890'),16,'0')

然后我检查
giro\uu
是否是一个数字,如下所示,使用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;
用于1.长度(giro)循环中的i_uuu
c_:=ASCII(SUBSTR(giro_,i_,1));
如果(cASCII('9')),则
返回FALSE;
如果结束;
端环;
我有一个场景,上面显示的SELECT查询不会拾取任何记录

这最终在FOR循环中引入了一个异常,错误为ORA-06502和ORA-06512

据我了解,原因是长度(giro)

1..LENGTH(giro_)
失败,因为
giro_
值(长度为空)的长度无法转换为数字

我的问题是,在这个场景中,
giro\ucode>是空字符串还是空字符串?
这里到底发生了什么


谢谢

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

该规则的例外情况是,如果其(
LENGTH
)参数是空字符串(在Oracle中,它等于
NULL
)-则长度也是未知的(
NULL
):

在这种情况下,请修改代码,使其包含
NVL
功能,例如:

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

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

虽然我逐渐意识到空字符串和NULL在Oracle中是相同的,
LENGTH
是极少数的缺点之一。如果是空字符串,则返回NULL而不是零。奇怪的是,您看到了使用
DISTINCT
的必要性,但却看到它保证只得到一个结果行。这可能表明数据模型不好或查询不太可靠。是的,我同意你的说法。我将尝试修改我的数据/查询:)谢谢您的输入!嗨,谢谢你的回答。我想你同意我在这个问题上的观点了吧?当我说“1..LENGTH(giro_uu)失败,因为giro_u值的长度无法转换为数字”时,我的意思是代码失败,因为LENGTH的返回值在这里为NULL。所以,循环不能从1变为NULL,它应该是1到某个数字。不客气。很抱歉,如果我误解了你说的话。
FOR i_ IN 1 .. NVL(LENGTH( giro_ ), 0) LOOP