1

好的,我正在尝试获取 Oracle 11g 中 DATE 列的字符串值以传递给 C# 应用程序中的 UI(通过 WCF)。我想准确地显示我在 SQL Developer 中拉回 C# 中的字符串变量的内容。相反,当我有一个 Date 列时,我得到了一些非常古怪的解析 DateTime 值。

例子:

SQL Developer 中的价值:26-AUG-75
VS 中来自 myDataRow[0].ToString() 的值:8/26/0975 12:00:00 AM

SQL Developer 中的价值:01-JUL-76
VS 中来自 myDataRow[0].ToString() 的值:7/1/1776 12:00:00 AM

Oracle 日期看起来正确。VS 没有。谢谢,本富兰克林和烈士爱德华。有没有搞错?

SQL 很简单。我显然在更改字段名称,但就是这样:

SELECT DISTINCT(MyDate) FROM
User1.TableOfDates@DateTableLink 
WHERE MyDate IS NOT NULL ORDER BY
MyDate

向数据库抛出 SQL 的共享代码也很简单。我将在这里对其进行大量审查,但到目前为止,它在其他任何地方都运行良好,而且我认为这里有重要的东西:

internal Oracle.DataAccess.Client.OracleConnection oracleConn;
...
DataTable dtReturn = new DataTable();
Oracle.DataAccess.Client.OracleCommand cmdTemp = null;
string strScrub = "";

// strScrub is magically loaded with SQL, which is, 
// if you grab it with a breakpoint here, after it's 
// scrubbed, equal to what I've written, above

cmdTemp = new Oracle.DataAccess.Client.OracleCommand(strScrub, this.oracleConn);
Oracle.DataAccess.Client.OracleDataReader dr = cmdTemp.ExecuteReader();
dtReturn.Load(dr);
dr.Dispose();
...
return dtReturn;

那部分有效。我只在此处包含它,以防我应该注意使用 Oracle.DataAccess 的某些东西。一切都打开和关闭并收集得很好。我们每天在开发中通过它发送数百个命令,并且在部署中至少有数千个。

这是第一个值 (26-AUG-75) 的即时窗口中的一些信息,现在代表从上面的代码中提取dr的单个值:DataRowDataTable

? DateTime.Parse(dr[0].ToString())
{8/26/0975 上午 12:00:00}
    日期:{8/26/0975 12:00:00 AM}
    天数:26
    DayOfWeek: 星期六
    日期:238
    小时:0
    种类:未指定
    毫秒:0
    分钟:0
    月:8
    第二:0
    滴答声:307569312000000000
    时间:{00:00:00}
    年份:975

只需? dr[0]-- 给出同样的结果:

?dr[0]
{8/26/0975 上午 12:00:00}
    日期:{8/26/0975 12:00:00 AM}
    天数:26
    DayOfWeek: 星期六
    日期:238
    小时:0
    种类:未指定
    毫秒:0
    分钟:0
    月:8
    第二:0
    滴答声:307569312000000000
    时间:{00:00:00}
    年份:975

现在有趣的是,当它只是 Oracle 中的一个日期时,它是一个 DateTime。也许我错过了关于 Oracle Dates 的一些东西......

? 博士[0].GetType()
{Name = "DateTime" FullName = "System.DateTime"}

无论如何,如果我能达到我在 SQL Developer 中看到的相同值(例如,26-AUG-75),我很好。我可以接受并做任何我想做的事情。

隐式转换在哪里进行,我怎样才能更早地进入那里?

我应该补充一点,我无法使用 SELECT 语句 & 获得创意TO_CHAR。这是一个相当复杂的自动化过程,它根据用户标准构建查询。因此,更改此 SELECT 将是“给机器一条鱼”而不是“教机器钓鱼”的答案。任何字段都可以是这种格式的日期,因此打开 GetType 值并在 C# 中解析一些创造性的方式是可以的,但更改 SQL 则不行。

编辑使用这里的建议:

select dump(sysdate)today from dual; 

在上面的 SQL 中使用dump,从 SQL Developer 运行,我得到: Typ=12 Len=7: 119,175,8,26,1,1,1对于 26-AUG-75 的行。所以甲骨文得到了正确的日期。

按照此处找到的转换说明...

119 - 100 "excess" = 19 centuries == 1900
175 - 100 "excess" = 75     years ==   75

那是1975年。

4

1 回答 1

3

您的问题尚不清楚,但我假设您实际上想要 1975 年和 1976 年?

我强烈怀疑值 0975 和 1776实际上是数据库中的值。您在 SQL Developer 中的值只是 2 位数年份的表示。我怀疑如果您执行另一种使用 4 位数年份表示的字符串转换,您会看到相同的值。

因此,验证上述内容正确后的选项:

  • 找出坏数据是如何进入系统的,修复它(这样你就不会得到更多坏数据),然后修复现有数据。
  • 通过忽略除年份的最后两位数字之外的所有数字,并强制它们进入适当的世纪来解决此问题。请注意,可能会有一些“有趣”的数据,就 2 月 29 日而言,在某些年份有效,但在其他年份无效......

顺便说一句,我强烈建议转换为DateTime而不是转换为字符串然后解析它。

于 2012-08-29T19:39:26.140 回答