在Oracle中通过参数插入日期

时间:2015-07-02 12:19:08

标签: c# oracle

我在oracle中设置了一个存储过程。它接受许多参数。其中有几个属于“日期”类型。

在我的应用程序中,我检查一个值并指定默认值,如果它符合以下某个条件:

private static string FixInputString(string s)
{
    return string.IsNullOrEmpty(s) ? "-1" : s;
}

然后,我将其格式化为Oracle的日期

private static string ConvertToOracleDate(string s)
{
    var temp = string.IsNullOrEmpty(s) || string.Equals(s, "-1", StringComparison.InvariantCultureIgnoreCase)
        ? "01-Jan-1900" : Convert.ToDateTime(s).ToString("dd-MMM-yyyy");
    return temp;
}

当我运行它时,我在变量中有这个值:

enter image description here

然后我设置参数:

new SpParameterOracle
{
    Key = "p_SGND_DT",
    Value = ConvertToOracleDate(FixInputString(form.SignedOnDate)),
    Direction = ParameterDirection.Input,
    Type = OracleDbType.Date
},

以下是我将其分配给OracleCommand时参数的内容: enter image description here

我的存储过程,按如下方式处理输入参数:

decode(TO_CHAR(p_SGND_DT, 'mm/dd/yyyy'), '01/01/1900', null, TO_DATE(p_SGND_DT, 'DD-MON-YYYY')),

我也试过这个:

decode(TO_CHAR(p_SGND_DT, 'mm/dd/yyyy'), '01/01/1900', null, p_SGND_DT),

表中的结果值是:

enter image description here

为什么它从1901年1月1日改为2001年1月1日???

到目前为止,我尝试在应用程序和存储过程中切换格式,结果仍然相同。

任何想法都会受到赞赏。

正如其中一个答案所述,转换是这个问题的罪魁祸首。

我没有处理它,而是修改了存储过程的逻辑以及代码。 在存储过程中,我将所有必填字段设为可选字段,如下所示:

p_SGND_DT in date default null,

然后我只需在表格中插入一个值。 在应用程序方面,我修改了代码以仅发送使用的参数并省略其余的参数,这些参数为空。

感谢您帮助并指出我正确的方向。非常感谢。

1 个答案:

答案 0 :(得分:2)

问题在于存储过程中的TO_DATE(p_SGND_DT, 'DD-MON-YYYY')p_sgnd_dt是DATE数据类型(或者暗示),因此无需再次尝试将其转换为日期。

你应该只对字符串的东西使用to_date。

如果对已经是日期的事情做了TO_DATE(),那么Oracle必须将日期隐式转换回字符串,然后再将其重新转换为日期。因此,TO_DATE(p_SGND_DT, 'DD-MON-YYYY')实际上变为:

TO_DATE(TO_CHAR(p_SGND_DT, <nls_date_format parameter>), 'DD-MON-YYYY')

默认的nls_date_format是&#39; DD-MON-YY&#39;,这意味着您现在已经丢失了当年的前两位数字,当Oracle尝试将其转换回四位数年份时,它会猜到前两位数字是什么 - 并让他们错了。

我不确定你为什么要将你的参数转换为字符串来进行比较,但最好的情况是:它会更好:

decode(p_SGND_DT, to_date('01/01/1900', 'dd/mm/yyyy'), null, p_SGND_DT)

或者,如果您尝试从传入日期中删除任何时间元素:

decode(p_SGND_DT, to_date('01/01/1900', 'dd/mm/yyyy'), null, trunc(p_SGND_DT))