Oracle时间戳数据类型缺少时间信息

发布于 2024-10-27 23:36:36 字数 807 浏览 5 评论 0原文

我试图从 .net 将日期时间值存储在 oracle 中,当日期时间持久保存到数据库时,时间信息丢失。

数据库是 11g,我使用 Oracle.DataAccess 程序集版本 2.111.6.20 中的 OracleCommand 和 OracleConnection 类。

我在.net中有一个数据层,它调用一个oracle存储过程。相关日期字段的参数是一个 IN 参数,它被标记为 TimeStamp 数据类型。表中的字段也定义为时间戳。

// Add the parameter to the OracleCommand
var dt = new DateTime(2011,07,07,10,0,0);
cmd.Parameters.Add("RECEIVED", OracleDbType.TimeStamp, 6, dt, System.Data.ParameterDirection.Input);
cmd.ExecuteNonQuery();

参数的值确实包含时间信息(上午 10 点),但是当它持久化到数据库时,时间信息丢失了。

我的存储过程看起来像这样...

create or replace
PROCEDURE DATA_INSERT 
(
  ID OUT NUMBER
, RECEIVED IN TIMESTAMP
) AS 
BEGIN

  ID := MY_SEQUENCE.nextval;
  INSERT INTO DATA (ID, RECEIVED) VALUES (ID, RECEIVED);

END DATA_INSERT;

知道为什么时间戳会丢失时间信息吗?

I'm trying to store a datetime value in oracle from .net and when the date time gets persisted to the db, the time information is missing.

The db is 11g and I'm using the OracleCommand and OracleConnection classes from the Oracle.DataAccess assembly version 2.111.6.20.

I have a data layer in .net which calls an oracle stored procedure. The parameter for the datefield in question is an IN parameter which is marks as a TimeStamp datatype. The field in the table is also defined as a TimeStamp.

// Add the parameter to the OracleCommand
var dt = new DateTime(2011,07,07,10,0,0);
cmd.Parameters.Add("RECEIVED", OracleDbType.TimeStamp, 6, dt, System.Data.ParameterDirection.Input);
cmd.ExecuteNonQuery();

The value of the parameter does contain the time information (10am), but when it gets persisted to the db, the time info is missing.

My stored procedure looks something like this...

create or replace
PROCEDURE DATA_INSERT 
(
  ID OUT NUMBER
, RECEIVED IN TIMESTAMP
) AS 
BEGIN

  ID := MY_SEQUENCE.nextval;
  INSERT INTO DATA (ID, RECEIVED) VALUES (ID, RECEIVED);

END DATA_INSERT;

Any idea why the timestamp is losing the time information?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

只有影子陪我不离不弃 2024-11-03 23:36:36

好吧,我想我已经弄清楚问题是什么了。在上面的示例中,为了简洁起见,我从存储过程中省略了一些附加参数。我在查询中还有其他参数,其中一些参数的数据类型为 DATE。因此,考虑下表...

  CREATE TABLE TEST (DATE_FIELD DATE, TIMESTAMP_FIELD TIMESTAMP);

以及存储过程...

CREATE OR REPLACE PROCEDURE TEST_INSERT ( P_DATE IN DATE, P_TIMESTAMP IN TIMESTAMP ) AS 
BEGIN
  INSERT INTO TEST(DATE_FIELD, TIMESTAMP_FIELD) VALUES(P_DATE, P_TIMESTAMP);
END TEST_INSERT;

以及下面的c#...

using (var cmd = new OracleCommand("TEST_INSERT", conn))
{
    cmd.CommandType = System.Data.CommandType.StoredProcedure;
    cmd.Parameters.Add("P_TIMESTAMP", OracleDbType.TimeStamp
        , new DateTime(2011, 07, 07, 10, 0, 0), System.Data.ParameterDirection.Input);
    cmd.Parameters.Add("P_DATE", OracleDbType.Date
        , new DateTime(2011, 07, 08), System.Data.ParameterDirection.Input);

    cmd.ExecuteNonQuery();
}

结果将是...

DATE_FIELD: 11-07-07 
TIMESTAMP_FIELD: 11-07-08 00:00:00.000000000

因此,即使参数被命名,参数的名称似乎也无关紧要并且参数添加到 .net 中的参数集合的顺序将决定存储过程中参数的值。

因此,在 C# 代码片段中,如果将参数添加到集合中的顺序颠倒过来...

cmd.Parameters.Add("P_DATE", OracleDbType.Date
     , new DateTime(2011, 07, 08), System.Data.ParameterDirection.Input);
cmd.Parameters.Add("P_TIMESTAMP", OracleDbType.TimeStamp
     , new DateTime(2011, 07, 07, 10, 0, 0), System.Data.ParameterDirection.Input);

那么结果将是...

DATE_FIELD: 11-07-08 
TIMESTAMP_FIELD: 11-07-07 10:00:000000000

Ok, I think I've figured out what the issue is. In the example above I omitted some additional parameters from my stored proc for berevity. I have other parameters in the query, some of which are of datatype DATE. So, consider the following table...

  CREATE TABLE TEST (DATE_FIELD DATE, TIMESTAMP_FIELD TIMESTAMP);

And the stored procedure...

CREATE OR REPLACE PROCEDURE TEST_INSERT ( P_DATE IN DATE, P_TIMESTAMP IN TIMESTAMP ) AS 
BEGIN
  INSERT INTO TEST(DATE_FIELD, TIMESTAMP_FIELD) VALUES(P_DATE, P_TIMESTAMP);
END TEST_INSERT;

And the following c#...

using (var cmd = new OracleCommand("TEST_INSERT", conn))
{
    cmd.CommandType = System.Data.CommandType.StoredProcedure;
    cmd.Parameters.Add("P_TIMESTAMP", OracleDbType.TimeStamp
        , new DateTime(2011, 07, 07, 10, 0, 0), System.Data.ParameterDirection.Input);
    cmd.Parameters.Add("P_DATE", OracleDbType.Date
        , new DateTime(2011, 07, 08), System.Data.ParameterDirection.Input);

    cmd.ExecuteNonQuery();
}

The result will be...

DATE_FIELD: 11-07-07 
TIMESTAMP_FIELD: 11-07-08 00:00:00.000000000

So, even though the parameters are named, it seems as though the name of the parameter is irrelevant and that the order in which parameters are added to the Parameters collection in .net will determine the values of the parameters in the stored procedure.

So, in the c# snippet if you reverse the order in which the parameters are added to the collection to...

cmd.Parameters.Add("P_DATE", OracleDbType.Date
     , new DateTime(2011, 07, 08), System.Data.ParameterDirection.Input);
cmd.Parameters.Add("P_TIMESTAMP", OracleDbType.TimeStamp
     , new DateTime(2011, 07, 07, 10, 0, 0), System.Data.ParameterDirection.Input);

then the result will be...

DATE_FIELD: 11-07-08 
TIMESTAMP_FIELD: 11-07-07 10:00:000000000
网名女生简单气质 2024-11-03 23:36:36

当您发出此选择时,您会看到什么:

SELECT TO_CHAR(RECEIVED, 'MM/DD/YYYY HH24:MI:SS') FROM data WHERE ID = <value>;

When you issue this select, what do you see:

SELECT TO_CHAR(RECEIVED, 'MM/DD/YYYY HH24:MI:SS') FROM data WHERE ID = <value>;
眼波传意 2024-11-03 23:36:36

我将您的代码运行到表中,结果是 (07-JUL-11 10.00.00.000000000 AM ),这是预期的。我发现您对列和参数使用相同的名称,尝试在变量名称前面添加“p_”,看看它是否有效,

这就是我运行的:
在 Oracle 中:

 create table t_data(received timestamp);

在 C# 中

  Oracle.DataAccess.Client.OracleCommand cmd = new Oracle.DataAccess.Client.OracleCommand("BEGIN INSERT INTO t_DATA (RECEIVED) VALUES (:RECEIVED); END;",con);
        // Add the parameter to the OracleCommand
        DateTime dt = new DateTime(2011,07,07,10,0,0);
        cmd.Parameters.Add("RECEIVED", OracleDbType.TimeStamp, 6, dt, System.Data.ParameterDirection.Input);
        cmd.ExecuteNonQuery();

返回 Oracle

   select * from t_data            

RECEIVED                  
------------------------- 
07-JUL-11 10.00.00.000000000 AM 

如果有的话,请尝试类似的操作,看看它是否有效,然后返回并检查您的过程,看看是否有东西看起来有问题(比如任性的截断)

I ran your code into a table and my results were (07-JUL-11 10.00.00.000000000 AM ) which is what is expected. I see that you are using the same name for the column and parameter, try pre-pending a "p_" infront of the variable name and see if it works

this is what I ran:
In Oracle:

 create table t_data(received timestamp);

in c#

  Oracle.DataAccess.Client.OracleCommand cmd = new Oracle.DataAccess.Client.OracleCommand("BEGIN INSERT INTO t_DATA (RECEIVED) VALUES (:RECEIVED); END;",con);
        // Add the parameter to the OracleCommand
        DateTime dt = new DateTime(2011,07,07,10,0,0);
        cmd.Parameters.Add("RECEIVED", OracleDbType.TimeStamp, 6, dt, System.Data.ParameterDirection.Input);
        cmd.ExecuteNonQuery();

back to Oracle

   select * from t_data            

RECEIVED                  
------------------------- 
07-JUL-11 10.00.00.000000000 AM 

If anything, try something like this to see if it works then go back and check your procedure and see if something doesn't look awry (like a wayward trunc)

网白 2024-11-03 23:36:36

如果您使用Oracle提供的dll,它默认按顺序绑定变量。在执行之前添加以下代码行以绑定到名称。

cmd.BindByName = true;

If you are using the Oracle provided dll, it binds variables ordinally by default. Add the following line of code before you execute to bind to the names.

cmd.BindByName = true;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文