【问题标题】:How to solve SQL error: ORA-01843: not a valid month如何解决 SQL 错误:ORA-01843: not a valid month
【发布时间】:2018-04-23 09:13:16
【问题描述】:

知道我的查询有什么问题吗?

我正在尝试更新数据库的一行,但我使用的查询导致异常。

UPDATE Table1
SET CHANGE_DELIVERY_REASON    = 'Card Activation',
CHANGE_DELIVERY_NOTE        = 'ACTIVATION SUCCESS [1 OK - 2 OK]',
RECONCILIATION_STATUS       = 1 ,
RECONCILIATION_LAST_UPDATED = '23/4/2018 12:00:00 AM',
RECONCILIATION_COUNT        = '6',
ACTIVATION_FAILURE          = 'SUCCESS';

我收到此错误:

“SQL 错误:ORA-01843:无效月份”

我没有弄清楚我的查询出了什么问题。

updateQuery = " UPDATE " + clsUtility.GetMasterTable() + " SET ";
updateQuery += "   CHANGE_DELIVERY_REASON = 'Card Activation', ";
updateQuery += "   CHANGE_DELIVERY_NOTE = '" + notes + "', ";
updateQuery += "   RECONCILIATION_STATUS = 1 , ";
updateQuery += "   RECONCILIATION_LAST_UPDATED = '" + DateTime.Today + "', ";
updateQuery += "   RECONCILIATION_COUNT = '" + reconciliation_count + "',";
updateQuery += "   ACTIVATION_FAILURE = '" + resultPart + "', ";

【问题讨论】:

  • 理想情况下,您将使用 parameters 并停止将 datacode 混合在一个字符串中,然后必须被拉开并重新解析为适当的数据类型。
  • 学习使用参数,而不是使用字符串修改查询。

标签: c# sql .net oracle


【解决方案1】:

您的问题是您给出的日期的格式,这是在其他答案中处理的。您将需要它用于其他日期字段,因此请务必查看它。

但是,对于这种特殊情况,您可以简单地停止使用本地日期并让数据库完成工作:

RECONCILIATION_LAST_UPDATED = trunc(sysdate)

附带说明:请在您的查询中使用参数绑定。您对SQL injection 攻击持开放态度。

通过参数绑定,您不仅可以避免SQL注入攻击,而且不必担心实际上不需要格式化存储的数据的格式字符串:

using (var connection = new SqlConnection())
{
    using (var command = connection.CreateCommand())
    {
        command.CommandText = "UPDATE " + clsUtility.GetMasterTable() + " SET RECONCILIATION_LAST_UPDATED = :last_updated, CHANGE_DELIVERY_NOTE = :delivery_note";

        var parameterLastUpdated = command.CreateParameter();

        parameterLastUpdated.ParameterName = ":last_updated";
        parameterLastUpdated.SqlDbType = SqlDbType.DateTime;
        parameterLastUpdated.Direction = ParameterDirection.Input;
        parameterLastUpdated.Value = DateTime.Today;

        command.Parameters.Add(parameterLastUpdated);

        var parameterDelivery = command.CreateParameter();

        parameterDelivery.ParameterName = ":delivery_note";
        parameterDelivery.SqlDbType = SqlDbType.NVarChar;
        parameterDelivery.Direction = ParameterDirection.Input;
        parameterDelivery.Value = "Some string you want in notes";

        command.Parameters.Add(parameterDelivery);

        command.ExecuteNonQuery();
    }
}

【讨论】:

  • 您不希望在 Oracle 中使用 @param_name - 这是 SQL Server 语法 - 您需要一个冒号 : 前缀。
【解决方案2】:

你应该使用TO_DATE()函数。

将你的一行改为这一行:

updateQuery += "   RECONCILIATION_LAST_UPDATED = TO_DATE('" + 
                   DateTime.Today + "', 'DD/MM/YYYY HH:MI:SS AM'), ";

更正的代码:

updateQuery = " UPDATE " + clsUtility.GetMasterTable() + " SET ";
updateQuery += "   CHANGE_DELIVERY_REASON = 'Card Activation', ";
updateQuery += "   CHANGE_DELIVERY_NOTE = '" + notes + "', ";
updateQuery += "   RECONCILIATION_STATUS = 1 , ";
updateQuery += "   RECONCILIATION_LAST_UPDATED = TO_DATE('" + DateTime.Today + "', 'DD/MM/YYYY HH:MI:SS AM'), ";           //This Line is changed
updateQuery += "   RECONCILIATION_COUNT = '" + reconciliation_count + "',";
updateQuery += "   ACTIVATION_FAILURE = '" + resultPart + "', ";

一般语法:

Oracle/PLSQL 中 TO_DATE 函数的语法是:

TO_DATE( string1 [, format_mask] [, nls_language] )

更多信息请点击链接:

https://www.techonthenet.com/oracle/functions/to_date.php

【讨论】:

  • 我做对了吗,因为我仍然收到相同的错误 updateQuery += " RECONCILIATION_LAST_UPDATED = TO_DATE('" + DateTime.Today + "', 'DD/MM/YYYY HH:MI:SS '), ";
  • 你假设所有系统都会为DateTime.Today.ToString()提供相同的输出...
  • @Lara 不要使用字符串连接来进行 SQL 查询。如果notes = 'fake\', CREDIT_LIMIT = 1000000000, other_column = \'fake' 会发生什么?您刚刚允许某人设置了 10 亿信用额度!使用参数化查询。
  • 必须在 VS 2017 上使用它来获得 Oracle 的 ADO .NET 连接 [ADO NET Source [2]] 错误:System.Data.OleDb.OleDbException (0x80040E07):ORA-01843:不是一个有效的月份。谢谢。在数据流中有 Oracle Source 的 VS 2019 上不一样。
【解决方案3】:

问题是您的日期格式

updateQuery = " UPDATE " + clsUtility.GetMasterTable() + " SET ";
updateQuery += "   CHANGE_DELIVERY_REASON = 'Card Activation', ";
updateQuery += "   CHANGE_DELIVERY_NOTE = '" + notes + "', ";
updateQuery += "   RECONCILIATION_STATUS = 1 , ";
updateQuery += "   RECONCILIATION_LAST_UPDATED = TO_DATE('" + DateTime.Today + "','DD/MM/YYYY HH:MI:SS AM'), ";
updateQuery += "   RECONCILIATION_COUNT = '" + reconciliation_count + "',";
updateQuery += "   ACTIVATION_FAILURE = '" + resultPart + "', ";

试试这个

【讨论】:

  • 我不是手写代码,我得到的是今天的日期 updateQuery += " RECONCILIATION_LAST_UPDATED = '" + DateTime.Today + "', ";
  • sqlfiddle.com/#!4/a4729/3 我在小提琴中测试它并在不刷新的情况下对其进行编辑这并不意味着我要复制它@Nishant Gupta
  • 嘿,如果您认为我抄袭了您@Nishant Gupta,您无需删除您所说的内容
猜你喜欢
  • 2017-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多