【问题标题】:Passing char value to function将 char 值传递给函数
【发布时间】:2019-12-11 12:16:39
【问题描述】:

我有以下功能:

CREATE OR REPLACE FUNCTION BANINST1."F_COC_AUTO_AWARD_FILTER" (pidm number) return number
as
return_field number;

cursor get_pidm is
select distinct SHRDGMR.SHRDGMR_PIDM
from SATURN.SHRDGMR SHRDGMR,
     SATURN.SORLCUR SORLCUR,
     SATURN.SORLFOS SORLFOS,
     DWSCHEMA.DAP_AUDIT_DTL@LINKDWTEST
where SORLCUR.SORLCUR_PIDM = SHRDGMR.SHRDGMR_PIDM
     and SORLFOS.SORLFOS_PIDM = SORLCUR.SORLCUR_PIDM
     and SORLCUR.SORLCUR_LEVL_CODE = SHRDGMR.SHRDGMR_LEVL_CODE
     and SORLCUR.SORLCUR_DEGC_CODE = SHRDGMR.SHRDGMR_DEGC_CODE
     and SORLFOS.SORLFOS_TERM_CODE = SORLCUR.SORLCUR_TERM_CODE
     and SHRDGMR.SHRDGMR_PIDM = pidm
     and SHRDGMR.SHRDGMR_DEGS_CODE = 'AW'
     and SORLCUR.SORLCUR_PROGRAM in ('STCC', 'CC')
     and DWSCHEMA.DAP_AUDIT_DTL.DAP_DEGREE in ('CPCC-CDS', 'CC1-CDS', 'CC2-CDS')
     and SORLFOS.SORLFOS_MAJR_CODE <> DWSCHEMA.DAP_AUDIT_DTL.DAP_AUD_VALUE2
     and trim(DWSCHEMA.DAP_AUDIT_DTL.DAP_STU_ID) = (select spriden_id from spriden where spriden_pidm = pidm and spriden_change_ind is null);

begin
   open get_pidm;
   fetch get_pidm into return_field;
   close get_pidm;

return return_field;
end;
/

这是从 where 子句对函数的调用:

baninst1.f_coc_auto_award_filter@test(RAD_PRIMARY_MST.RAD_USER_DEF1) is not null

该函数接受数字数据类型参数。
传递的列 RAD_PRIMARY_MST.RAD_USER_DEF1 是 char(12) 数据类型,其值例如为 293858。
调用函数返回如下错误:ORA-01722: invalid number

我尝试通过几种不同的方式将数值传递给函数:

baninst1.f_coc_auto_award_filter@test(to_number(trim(RAD_PRIMARY_MST.RAD_USER_DEF1))) is not null
baninst1.f_coc_auto_award_filter@test(cast(RAD_PRIMARY_MST.RAD_USER_DEF1 as number(8))) is not null

所有尝试都返回相同的错误 ORA-01722: invalid number

如果我将 D_PRIMARY_MST.RAD_USER_DEF1 值硬编码为一个数字,则函数调用有效。

baninst1.f_coc_auto_award_filter@test(293858) is not null

如何将 char 值从 RAD_PRIMARY_MST.RAD_USER_DEF1 传递给函数?

【问题讨论】:

  • 在对 F_COC_AUTO_AWARD_FILTER 的调用中,数据库试图执行从 CHAR(12) 到 NUMBER 的隐式转换,并找到一个非数字字符,因此到 NUMBER 的转换失败。
  • 如果您因为无法控制的原因而被CHAR 卡住,我很同情您。否则,停止使用CHAR 并切换到标准字符串类型。

标签: sql oracle


【解决方案1】:

这可能是关键字:

293858

您确定该列中没有任何非数字值吗?使用该数据类型 (char),总会有疑问。如果您在其中存储数字,为什么不是number

此查询应返回导致代码中断的无效值。

select * from d_primary_mst where not regexp_like(rad_user_def1, '^\d+$')

另外,如果你传递一个字符串,为什么要强制函数接受一个数字?为什么不呢

CREATE OR REPLACE FUNCTION BANINST1.F_COC_AUTO_AWARD_FILTER 
  (pidm RAD_PRIMARY_MST.RAD_USER_DEF1%type) 
  return SHRDGMR.SHRDGMR_PIDM%type
as
  return_field SHRDGMR.SHRDGMR_PIDM%type;

  cursor get_pidm is
    select distinct SHRDGMR.SHRDGMR_PIDM ...

顺便说一句,创建Oracle对象时去掉双引号;它们只会引起问题。

【讨论】:

  • RAD_USER_DEF1 列中似乎存在非数字值。添加此代码解决了该问题。和 REGEXP_LIKE (trim(RAD_PRIMARY_MST.RAD_USER_DEF1),'^[[:digit:]]+$')
  • 对;这通常导致此类问题的原因,尤其是当表包含许多行时,您看不出有什么问题,因为选择一些示例行看起来没问题。好的,很高兴你修好了!
猜你喜欢
  • 2023-03-29
  • 2012-07-26
  • 2023-03-06
  • 2012-05-10
  • 1970-01-01
  • 2021-09-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多