为什么我会得到一个"无效的月份"使用C#在Oracle数据库中存储日期时出错?

时间:2017-06-01 16:04:45

标签: c# oracle to-date

我正在尝试使用C#更新Oracle表。 我写了一个函数

public int UpdateInfo(String emplid, bool i4, char?status,String bdate)
{
    int result = -1;
    try
    {
        using (OracleConnection conn = new OracleConnection(ConfigurationManager.ConnectionStrings["OracleOleDB"].ConnectionString))
        {
            conn.Open();
            OracleCommand cmdN = conn.CreateCommand();
            cmdN.CommandText= "UPDATE INFO SET I4=:i4,Status=:status,Bdate=(SELECT TO_DATE(:bdate,'DD_MON_RR'))where EMPLID =:emplid;";
            cmdN.Parameters.Add(":I4",i4);

            cmdN.Parameters.Add(":Status", status);
            cmdN.Parameters.Add(":EMPLID",emplid);
            cmdN.Parameters.Add(":Bdate", bdate);

            //below code I tried as well
            //  OracleCommand cmd = new OracleCommand("UPDATE INFO SET I4 = :I4,Status=:Status,Bdate=TO_DATE(:Bdate,'DD_MON_RR','NLS_DATE_LANGUAGE,AMERICAN') WHERE EMPLID =:EMPLID;", conn);
            //cmd.Parameters.Add(":I4", OracleDbType.Char).Value = (i4 ? 'Y' : 'N');
            //cmd.Parameters.Add(":Status", OracleDbType.Char).Value = status;
            //cmd.Parameters.Add(":EMPLID", OracleDbType.Varchar2).Value = emplid;
            //    cmd.Parameters.Add(":Bdate", OracleDbType.Date).Value = Bdate;

            result = cmdN.ExecuteNonQuery();
            conn.Close();
        }

    }

我收到错误无效的月份。 最初我收到错误无效数据所以注释掉了代码。

如果我直接从Visual Studio运行相同的查询,它会存储数据。 我在Visual Studio中使用以下查询

UPDATE INFO SET Status='S',Bdate=TO_DATE('01-June-2017','DD_MON_RR') WHERE EMPLID =00016106;

寻求帮助来解决这个问题。

2 个答案:

答案 0 :(得分:2)

将实际日期传递给方法而不是字符串,并将日期值用作参数而不进行任何转换,即:

public int UpdateInfo(...,DateTime bdate)
{
    cmdN.CommandText= "UPDATE INFO SET I4=:i4,Status=:status,Bdate=:bdate where EMPLID =:emplid;";            
    ...
    cmdN.Parameters.Add(":Bdate", bdate);
    ...
}

查询参数最重要的优点之一是您可以传递实际的强类型值,而不是将小数或日期转换为字符串,并且不得不使用本地化和格式。

另一个重要因素是在WHERE子句上使用TO_DATE之类的函数可以防止数据库使用索引。数据库必须扫描所有行以在过滤之前计算函数结果。

答案 1 :(得分:0)

对我有用的是使用参数传递日期,并在c#中预先格式化它。

示例...请注意语法,我的存储过程参数是从字典构建的

{" p_MSG_DATE",System.DateTime.Now.ToString(" MM / dd / yyyy HH:mm:ss")}

存储过程中的

RCV_DATE = TO_DATE(p_MSG_DATE,' MM / DD / YYYY HH24:MI:SS')