我在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;
}
当我运行它时,我在变量中有这个值:
然后我设置参数:
new SpParameterOracle
{
Key = "p_SGND_DT",
Value = ConvertToOracleDate(FixInputString(form.SignedOnDate)),
Direction = ParameterDirection.Input,
Type = OracleDbType.Date
},
以下是我将其分配给OracleCommand时参数的内容:
我的存储过程,按如下方式处理输入参数:
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),
表中的结果值是:
为什么它从1901年1月1日改为2001年1月1日???
到目前为止,我尝试在应用程序和存储过程中切换格式,结果仍然相同。
任何想法都会受到赞赏。
正如其中一个答案所述,转换是这个问题的罪魁祸首。
我没有处理它,而是修改了存储过程的逻辑以及代码。 在存储过程中,我将所有必填字段设为可选字段,如下所示:
p_SGND_DT in date default null,
然后我只需在表格中插入一个值。 在应用程序方面,我修改了代码以仅发送使用的参数并省略其余的参数,这些参数为空。
感谢您帮助并指出我正确的方向。非常感谢。
答案 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))