【问题标题】:ORA-01843: not a valid month error in oracle while updatingORA-01843: 更新时 oracle 中出现无效月份错误
【发布时间】:2017-12-07 10:05:02
【问题描述】:

我想用dd-mm-yy 的格式更新我的日期列。在我的数据库中,该列是date 数据类型。因此,在更新时,我将数据发送为

05-12-2017 但出现错误

ORA-01843: 月份无效

在我的存储过程中,我将其发送为

HOTO_ACCEPTENCE_DATE = TO_DATE(PHOTO_ACCEPTENCE_DATE, 'dd-m-yy'),

我的完整程序:

PROCEDURE UPD_WF_BY_FIBER_ENG
(
  PJOB_PROGRESS_ID IN TBL_FIBER_INV_JOB_PROGRESS.JOB_PROGRESS_ID%TYPE,
  PSTATUS_ID IN TBL_FIBER_INV_JOB_PROGRESS.STATUS_ID%TYPE,
  --PLIT_OFFERED_LENGTH IN TBL_FIBER_INV_JOB_PROGRESS.LIT_OFFERED_LENGTH%TYPE,
  PHOTO_ACTUAL_LENGTH IN TBL_FIBER_INV_JOB_PROGRESS.HOTO_ACTUAL_LENGTH%TYPE,
  PLIT_ACTUAL_LENGTH IN TBL_FIBER_INV_JOB_PROGRESS.LIT_ACTUAL_LENGTH%TYPE,

  PHOTO_ACCEPTENCE_DATE IN TBL_FIBER_INV_JOB_PROGRESS.HOTO_ACCEPTENCE_DATE%TYPE,
  PLIT_ACCEPTENCE_DATE IN TBL_FIBER_INV_JOB_PROGRESS.LIT_ACCEPTENCE_DATE%TYPE,

  PAPPROVED_BY IN TBL_FIBER_INV_JOB_PROGRESS.APPROVED_BY%TYPE,
  PREJECTED_BY IN TBL_FIBER_INV_JOB_PROGRESS.REJECTED_BY%TYPE,

  PAPPROV_REJECT_REMARK IN TBL_FIBER_INV_JOB_PROGRESS.APPROV_REJECT_REMARK%TYPE,

  PMODIFIED_BY IN TBL_FIBER_INV_JOB_PROGRESS.MODIFIED_BY%TYPE,
  PUMS_GROUP_ASS_BY_ID IN TBL_FIBER_INV_JOB_PROGRESS.UMS_GROUP_ASS_BY_ID%TYPE,
  PUMS_GROUP_ASS_BY_NAME IN TBL_FIBER_INV_JOB_PROGRESS.UMS_GROUP_ASS_BY_NAME%TYPE,
  PUMS_GROUP_ASS_TO_ID IN TBL_FIBER_INV_JOB_PROGRESS.UMS_GROUP_ASS_TO_ID%TYPE,
  PUMS_GROUP_ASS_TO_NAME IN TBL_FIBER_INV_JOB_PROGRESS.UMS_GROUP_ASS_TO_NAME%TYPE,
  PISABDMISSING IN TBL_FIBER_INV_JOB_PROGRESS.ISABDMISSING%TYPE,
  --PSPVENDORXML IN XMLTYPE,
  POUTMSG OUT NVARCHAR2
)
AS
VCNTSPVENCNT NUMBER :=0;
BEGIN

  UPDATE TBL_FIBER_INV_JOB_PROGRESS
    SET STATUS_ID = PSTATUS_ID,
       -- LIT_OFFERED_LENGTH = PLIT_OFFERED_LENGTH,
        HOTO_ACTUAL_LENGTH = PHOTO_ACTUAL_LENGTH,
        LIT_ACTUAL_LENGTH = PLIT_ACTUAL_LENGTH,
        HOTO_ACCEPTENCE_DATE = TO_DATE(PHOTO_ACCEPTENCE_DATE, 'DD-MM-YY'),
        LIT_ACCEPTENCE_DATE = TO_DATE(PLIT_ACCEPTENCE_DATE,  'DD-MM-YY'),
        APPROVED_BY = PAPPROVED_BY,
        APPROVED_DATE = DECODE(PAPPROVED_BY,NULL,NULL,SYSDATE),
        REJECTED_BY = PREJECTED_BY,
        REJECTED_DATE = DECODE(PREJECTED_BY,NULL,NULL,SYSDATE),
        APPROV_REJECT_REMARK = PAPPROV_REJECT_REMARK,
        MODIFIED_BY = PMODIFIED_BY,
        MODIFIED_DATE = SYSDATE,
        UMS_GROUP_ASS_BY_ID = PUMS_GROUP_ASS_BY_ID,
        UMS_GROUP_ASS_BY_NAME = PUMS_GROUP_ASS_BY_NAME,
        UMS_GROUP_ASS_TO_ID = PUMS_GROUP_ASS_TO_ID,
        UMS_GROUP_ASS_TO_NAME = PUMS_GROUP_ASS_TO_NAME,
        ISABDMISSING = PISABDMISSING
    WHERE JOB_PROGRESS_ID   = PJOB_PROGRESS_ID;

更新

try
        {
            DBObject ObjDBObject = new DBObject(strConnectionString);
            string strProcedureName = strPackageName + ".UPD_WF_BY_FIBER_ENG";

            List<OracleParameter> lstParameters = new List<OracleParameter>();

            OracleParameter ObjOracleParameter = new OracleParameter("PJOB_PROGRESS_ID", FiberDataInsertion.PROG_ID);
            OracleParameter ObjOracleParameter1 = new OracleParameter("PSTATUS_ID", 1);
            OracleParameter ObjOracleParameter2 = new OracleParameter("PHOTO_ACTUAL_LENGTH", FiberDataInsertion.HOTO_ACTUAL_LENGTH);
            OracleParameter ObjOracleParameter3 = new OracleParameter("PLIT_ACTUAL_LENGTH", FiberDataInsertion.LIT_ACTUAL_LENGTH);
            OracleParameter ObjOracleParameter4 = new OracleParameter("PHOTO_ACCEPTENCE_DATE", FiberDataInsertion.HOTO_ACCP_DATE);
            OracleParameter ObjOracleParameter5 = new OracleParameter("PLIT_ACCEPTENCE_DATE", FiberDataInsertion.LIT_ACCP_DATE);
            OracleParameter ObjOracleParameter6 = new OracleParameter("PAPPROVED_BY", "NADEEM5.KHAN");
            OracleParameter ObjOracleParameter7 = new OracleParameter("PREJECTED_BY", "DB");
            OracleParameter ObjOracleParameter8 = new OracleParameter("PAPPROV_REJECT_REMARK", "this is test");
            OracleParameter ObjOracleParameter9 = new OracleParameter("PMODIFIED_BY", FiberDataInsertion.MODIFIED_BY);
            OracleParameter ObjOracleParameter10 = new OracleParameter("PUMS_GROUP_ASS_BY_ID", FiberDataInsertion.UMS_GROUP_ASS_BY_ID);
            OracleParameter ObjOracleParameter11 = new OracleParameter("PUMS_GROUP_ASS_BY_NAME", FiberDataInsertion.UMS_GROUP_ASS_BY_NAME);
            OracleParameter ObjOracleParameter12 = new OracleParameter("PUMS_GROUP_ASS_TO_ID", FiberDataInsertion.UMS_GROUP_ASS_TO_ID);
            OracleParameter ObjOracleParameter13 = new OracleParameter("PUMS_GROUP_ASS_TO_NAME", FiberDataInsertion.UMS_GROUP_ASS_TO_NAME);
            OracleParameter ObjOracleParameter14 = new OracleParameter("PISABDMISSING", FiberDataInsertion.MISS_ASBUILT);


            OracleParameter ObjOracleParameter15 = new OracleParameter
            {
                ParameterName = "POUTMSG",
                Size = 500,
                OracleDbType = OracleDbType.NVarchar2,
                Direction = ParameterDirection.Output
            };

            lstParameters.Add(ObjOracleParameter);
            lstParameters.Add(ObjOracleParameter1);
            lstParameters.Add(ObjOracleParameter2);
            lstParameters.Add(ObjOracleParameter3);
            lstParameters.Add(ObjOracleParameter4);
            lstParameters.Add(ObjOracleParameter5);
            lstParameters.Add(ObjOracleParameter6);
            lstParameters.Add(ObjOracleParameter7);
            lstParameters.Add(ObjOracleParameter8);
            lstParameters.Add(ObjOracleParameter9);
            lstParameters.Add(ObjOracleParameter10);
            lstParameters.Add(ObjOracleParameter11);
            lstParameters.Add(ObjOracleParameter12);
            lstParameters.Add(ObjOracleParameter13);
            lstParameters.Add(ObjOracleParameter14);
            lstParameters.Add(ObjOracleParameter15);


            strMessage = ObjDBObject.ExecuteNonQuery(strProcedureName, lstParameters);

        }
        catch (Exception)
        {                
            throw;
        }
        return strMessage;

还有错误详情

at Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure, Boolean bCheck) at Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, String procedure, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, Boolean bCheck) at Oracle.DataAccess.Client.OracleCommand.ExecuteNonQuery() at FiberInventoryPortal.Models.DAL.DBObject.ExecuteNonQuery(String strProcedureName, List1 lstParameters) in d:\Nadeem\FiberInventory_214\FiberInventoryPortal\FiberInventoryPortal\Models\DAL\DBObject.cs:line 114`

【问题讨论】:

  • 'dd-m-yy' 不是有效的日期格式。请准确发布您在做什么。 minimal reproducible example 最好。
  • 日期具有特定于 Oracle 的内部表示,而不是那种格式。看起来您正在尝试将日期变量/列值更新为另一个日期,但基于自身 - 尽管使用部分代码(缺少字符)很难确定。不要打电话给to_date() 已经是约会了...
  • @AlexPoole: 不调用to_date() 也不工作并给出同样的错误
  • 那么你仍然在某处进行隐式转换。显示一个完整的示例来演示问题(不是损坏的片段),包括如何声明变量等。
  • @AlexPoole:查看我调用日期函数的过程。还是不行

标签: oracle date stored-procedures plsql


【解决方案1】:
HOTO_ACCEPTENCE_DATE = TO_DATE(PHOTO_ACCEPTENCE_DATE, 'DD-MM-YY')

TO_DATE( date_string, format_model, nls_params ) 将字符串作为第一个参数,因此 Oracle 必须将非字符串参数隐式转换为字符串,并且实际上正在这样做:

HOTO_ACCEPTENCE_DATE = TO_DATE(
                         TO_CHAR(
                           PHOTO_ACCEPTENCE_DATE,
                           ( SELECT value 
                             FROM   NLS_SESSION_PARAMETERS
                             WHERE  parameter = 'NLS_DATE_FORMAT' )
                         ),
                         'DD-MM-YY'
                       )

如果NLS_DATE_FORMAT 会话参数与DD-MM-YY 不匹配,那么您将收到错误消息。由于NLS_DATE_FORMAT 是一个会话参数,并且可以由每个用户更改,因此依赖此参数是您的代码开始引发异常的一种方式,因为用户更改了他们的设置,而您的代码却永远不会改变。

你想做的只是使用:

HOTO_ACCEPTENCE_DATE = PHOTO_ACCEPTENCE_DATE,

因为您在将日期存储为日期时不需要将其转换为任何内容。

我想用dd-mm-yy 格式更新我的日期列。

日期没有格式 - 它是 stored internally to the database as 7-bytes(代表年、月、日、小时、分钟和秒),直到您使用的任何用户界面(即 SQL/Plus、SQL Developer、 Java 等)尝试将其显示给您,即用户,并将其转换为您认为有意义的内容(通常是字符串),日期具有格式。

【讨论】:

  • 也尝试删除它,但仍然遇到与not a valid month相同的错误
  • @VVVV - 你确定它仍然来自同一个地方吗?你对PLIT_ACCEPTENCE_DATE 做同样的事情,这也应该是一个简单的任务。
  • @AlexPoole:在设置日期时,我将 datepicker 中的格式设置为前端的dd-mm-yy。就是这样。即使我收到错误
  • @VVVV 你在这条线上也有同样的问题LIT_ACCEPTENCE_DATE = TO_DATE(PLIT_ACCEPTENCE_DATE, 'DD-MM-YY')
  • @VVVV 是在过程中的 SQL 语句上抛出错误,还是在调用过程并尝试将字符串而不是日期传递给过程时?
【解决方案2】:

你可以试试

HOTO_ACCEPTENCE_DATE = TO_DATE(PHOTO_ACCEPTENCE_DATE, 'dd-mm-yy'),

查看document 了解可能的组合

【讨论】:

    【解决方案3】:

    考虑到您发布的格式'dd-m-yy',月份部分似乎不正确。它应该是MM 而不是M

    参考: https://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm

    【讨论】:

    • 您确定您的输入是“05-12-2017”格式,而不是“12-05-2017”(美国)格式吗?这也可以解释问题。
    • @BrunoJCM - 12 和 5 都是有效月份...?
    • 当然可以,但我知道这个特定日期只是真实输入的一个示例,其他实例可能会进入程序并导致错误。
    猜你喜欢
    • 2014-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-15
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    相关资源
    最近更新 更多