【问题标题】:Oracle Date Format with input Parametres - PLSQL带有输入参数的 Oracle 日期格式 - PL SQL
【发布时间】:2015-01-27 13:26:51
【问题描述】:

我收到如下错误: ORA-01858 - 在需要数字字符的地方发现了一个非数字字符。 虽然它不是很准确,但我相信它与以下几行中的日期格式有关。

ELSIF par_report_eff_date_start IS NOT NULL AND par_report_eff_date_start = to_date(par_report_eff_date_start, 'fxdd-mm-yyyy')

ELSIF par_report_eff_date_end IS NOT NULL AND par_report_eff_date_end = to_date( par_report_eff_date_end ,'fxDD-MM-YYYY')

我正在尝试获取参数以在传入时以“dd/mm/yyyy”格式呈现日期,但我不知道如何解决这个问题。

我看过,但工作中的网络访问受限,所以我无法使用常规网站。

       procedure collect_mon_comm_bal_data_part (
  par_report_eff_date_start DATE DEFAULT NULL, --dd/mm/yyyy;
  par_report_eff_date_end  DATE DEFAULT NULL) --dd/mm/yyyy;
  is 

v_report_eff_date_start DATE;
v_report_eff_date_end DATE;

BEGIN

  IF par_report_eff_date_start IS NULL 
    THEN 
    -- Oracle job runs at the beginning of each month
      select trunc(trunc(sysdate,'Mon')-1,'Mon')
      into v_report_eff_date_start
      from dual;   -- Start of month Var
    ELSIF par_report_eff_date_start IS NOT NULL AND par_report_eff_date_start = to_char(par_report_eff_date_start, 'fxdd/mm/yyyy')
        THEN
          v_report_eff_date_start := par_report_eff_date_start;
          DBMS_OUTPUT.PUT_LINE(par_report_eff_date_start || 'Is The Start Date');
    ELSE  
          DBMS_OUTPUT.PUT_LINE(par_report_eff_date_start || 'Is is the wrong format, needs tp be in dd/mm/yyyy'); 
          GOTO the_end;
  END IF;


  IF par_report_eff_date_end IS NULL 
    THEN 
    -- Oracle job runs at the beginning of each month
      select  trunc(sysdate,'MM')-1
      into v_report_eff_date_end
      from dual;   -- Start of month Var
    ELSIF par_report_eff_date_end IS NOT NULL AND par_report_eff_date_end = to_char(par_report_eff_date_end, 'fxdd/mm/yyyy')
        THEN
          v_report_eff_date_end := par_report_eff_date_end;
          DBMS_OUTPUT.PUT_LINE(par_report_eff_date_end || 'Is The Start Date');
     ELSE
          DBMS_OUTPUT.PUT_LINE(par_report_eff_date_end || 'Is is the wrong format, needs tp be in dd/mm/yyyy');
            GOTO the_end;
  END IF;
END;

【问题讨论】:

  • 如何调用上述程序?我的猜测是调用过程将日期作为字符串而不是日期传递,并且该字符串的格式不正确。

标签: sql oracle date plsql


【解决方案1】:

您不想将date 转换为date。您想将其转换为字符串。所以试试:

to_char(par_report_eff_date_start, 'fxdd-mm-yyyy')

我不确定其余的逻辑应该做什么。但是,您使用to_date() 将值转换为日期,并使用to_char() 将值转换为字符串。

【讨论】:

  • 除了 Gordon 所说的之外,如果您对 DATE 数据类型中已经存在的内容执行 to_date(),Oracle 必须将日期隐式转换为字符串,然后再返回日期.它将使用设置的任何 nls_date_format 掩码(很可能是数据库的掩码,而不是您的客户端会话)来执行此操作。由于默认的 nls_date_format 掩码是“dd-MON-yy”,因此您很有可能会返回错误的日期。如果您这样做,请尝试查看返回的内容: select to_char(to_date(to_date('17/05/2080 21:03:32', 'dd/mm/yyyy hh24:mi:ss')), 'dd/mm/yyyy hh24:mi:ss') 来自双重;
【解决方案2】:

我注意到您有参数 par_report_eff_date_start 和变量 v_report_eff_date_start。您可能想比较以下行中的内容:

ELSIF par_report_eff_date_start 不为空且 par_report_eff_date_start = to_char(par_report_eff_date_start, 'fxdd/mm/yyyy')

但现在您将日期参数与从参数值派生的文本值进行比较。我不认为那是你想要的。 日期只是一个日期,在将其转换为另一种数据类型(如 VARCHAR2)时,您只需考虑格式掩码。 那么为什么不使用:

ELSIF par_report_eff_date_start 不为空且 trunc(par_report_eff_date_start) = trunc(sysdate, 'Mon')

我已将 trunc() 添加到参数值中,并且因为您想要每月的第一天(我猜!!),所以 trunc(sysdate, 'Mon') 就可以了。

【讨论】:

    【解决方案3】:

    谢谢 Gordon,我想我已经找到了解决办法。

           procedure collect_mon_comm_bal_data_part (   
        par_report_eff_date_start VARCHAR2 DEFAULT NULL, --dd/mm/yyyy;  
     par_report_eff_date_end  VARCHAR2 DEFAULT NULL) --dd/mm/yyyy;   is 
    
            v_report_eff_date_start DATE; v_report_eff_date_end DATE;
    
            BEGIN
    
              IF par_report_eff_date_start IS NULL 
                THEN 
                -- Oracle job runs at the beginning of each month
                  select trunc(trunc(sysdate,'Mon')-1,'Mon')
                  into v_report_eff_date_start
                  from dual;   -- Start of month Var
                ELSIF par_report_eff_date_start IS NOT NULL AND to_date(par_report_eff_date_start, 'dd/mm/yyyy') = to_date(par_report_eff_date_start,'fxdd/mm/yyyy') 
                    THEN
                      v_report_eff_date_start := to_date(par_report_eff_date_start, 'dd/mm/yyyy');
                      DBMS_OUTPUT.PUT_LINE(par_report_eff_date_start || 'Is The Start Date');
                ELSE  
                      DBMS_OUTPUT.PUT_LINE(par_report_eff_date_start || 'Is is the wrong format, needs tp be in dd/mm/yyyy'); 
                      GOTO the_end;   END IF;
    
    
              IF par_report_eff_date_end IS NULL 
                THEN 
                -- Oracle job runs at the beginning of each month
                  select  trunc(sysdate,'MM')-1
                  into v_report_eff_date_end
                  from dual;   -- Start of month Var
                ELSIF par_report_eff_date_end IS NOT NULL AND to_date(par_report_eff_date_end, 'dd/mm/yyyy') = to_date(par_report_eff_date_end,'fxdd/mm/yyyy') 
                    THEN
                      v_report_eff_date_end := to_date(par_report_eff_date_end, 'dd/mm/yyyy');
                      DBMS_OUTPUT.PUT_LINE(par_report_eff_date_end || 'Is The Start Date');
                 ELSE
                      DBMS_OUTPUT.PUT_LINE(par_report_eff_date_end || 'Is is the wrong format, needs tp be in dd/mm/yyyy');
                        GOTO the_end;   END IF;
    

    所以我希望它默认为每月运行,如果参数为空,则为上个月。我希望它在选定的日期运行,如果它们在执行时手动输入,这样我可以运行一年来建立一个适当的数据样本,随着它的变化而更新。

    我尝试传入虚假日期和空日期,但它们遇到异常或按预期运行一个月的数据,所以这对我有用。

    再次感谢各位,真的是我的帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-25
      • 2020-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多