【问题标题】:Format a date so it can be written into Oracle ("Not a valid month" error)格式化日期,以便将其写入 Oracle(“不是有效月份”错误)
【发布时间】:2017-09-10 19:55:19
【问题描述】:

找不到合适的语法。这是我在 ASP 方面的领域:

<input type="text" id="EI_Open_AuditStartDt" class="datepicker" runat="server" 
    name="EI_Open_AuditStartDt" value='<%#Eval("Audit_Start_Date") %>' 
    style="width: 100px" />

这是我在 C# 中的代码隐藏的一部分:

HtmlInputText EI_Open_AuditStartDt = (HtmlInputText)DataGrid_Open.Rows[e.RowIndex].FindControl("EI_Open_AuditStartDt");
TextBox EI_Open_TransCIT = (TextBox)DataGrid_Open.Rows[e.RowIndex].FindControl("EI_Open_TransCIT");

string StartDt = String.Format("{0:dd-mmm-yyyy}", EI_Open_AuditStartDt.Value);
string TransCIT = EI_Open_TransCIT.Text;

DataGrid_RootCauses.EditIndex = -1;

OracleConnection conn = GetConnection();
try
{
    using (OracleCommand cmd = new OracleCommand("CST_AMR_WRITE_OPENSTATUS", conn))
    {
        cmd.CommandType = CommandType.StoredProcedure;

        using (OracleDataAdapter da = new OracleDataAdapter(cmd))
        {
            cmd.Parameters.AddWithValue("v_StartDt", OracleType.DateTime).Value = StartDt;
            cmd.Parameters.AddWithValue("v_TransCIT", OracleType.VarChar).Value = TransCIT;

问题是,当它到达字符串 StartDt 时,它仍然将值视为“03/24/2017”而不是“24-MAR-17”,所以我得到“无效”月”错误。

谁能看出我做错了什么?

【问题讨论】:

  • 我的猜测是存储过程采用的是字符串而不是日期参数。
  • @GordonLinoff 它不会说不是有效的日期而不是月份吗?无论哪种方式,您都很可能是正确的,因为它说 OracleType.DateTime 并且插入了一个字符串(不是很好吗?)
  • 嗯,这是有道理的。那么我将如何正确格式化它以便可以将其作为日期传递?
  • 我建议使用ISO 8601 格式。即yyyy-MM-dd
  • 据我了解 Oracle DB 引发的错误,这意味着 oracle NLS_DATE_FORMATdd-mmm-yy 不同。如果可以访问 oracle 程序,您可以在那里设置 execute immediate 'alter session set nls_date_format = ''dd-mmm-yy'''; 这个命令,或者您可以在同一会话中从客户端执行它,或者将字符串文字格式更改为 db 格式。我猜你的数据库格式是DD/MM/YY

标签: c# oracle date


【解决方案1】:
  1. 验证存储在 Oracle DB 中的数据格式。

  2. 尝试以该格式将数据作为原始字符串插入并查看是否成功。

这会将您的调用代码从影响您的问题的可能变量中剔除。

  1. 如果这仍然不起作用,您必须查看存储过程并确定它是否在您不知情的情况下转换格式。

  2. 如果您无法查看存储过程,您将不得不在调用代码中尝试多种不同的格式,直到找到正确的格式。

【讨论】:

    【解决方案2】:

    我建议使用ISO 8601 格式插入值 - 即yyyy-MM-dd

    var StartDt = Date.ParseExact(EI_Open_AuditStartDt.Value,"dd-MM-yyyy", CultureInfo.InvariantCulture););
    //.....
    cmd.Parameters.AddWithValue("v_StartDt", OracleType.DateTime).Value = StartDt.ToString("yyyy-MM-dd");
    

    虽然,您很有可能可以取消参数添加中的日期格式,只需将其交给StartDt 对象即可。

    cmd.Parameters.AddWithValue("v_StartDt", OracleType.DateTime).Value = StartDt;
    

    【讨论】:

      【解决方案3】:

      我想出了这个,它奏效了:

      DateTime dt1 = Convert.ToDateTime(EI_Open_SubmissionDt.Value);
      var SubDt = String.Format("{0:dd-MMM-yyyy}", dt1);
      

      比我(几乎所有人)拥有更多 C#/Oracle 经验的人会愿意在其中戳漏洞吗?这是一个合法的答案,还是有潜在的问题?

      【讨论】:

        【解决方案4】:

        格式为 C# var StartDt = Date.FormatExact(EI_Open_AuditStartDt.Value, "DD/MM/YY"); 或是否与您的 database nls_date_format 格式完全相同。

        或者你可以使用 c# DateTime 并执行以下操作,注意函数返回 bool,你可以在 if 运算符中检查它,然后将 myDTvar 分配给命令参数。 DateTime myDTvar; DateTime.TryParseExact(StartDt, "dd-mmm-yyyy", null, DateTimeStyles.None, out myDTvar)

        【讨论】:

          猜你喜欢
          • 2015-03-08
          • 1970-01-01
          • 2018-09-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-04-19
          • 2020-10-18
          • 2018-12-02
          相关资源
          最近更新 更多