我正在尝试在.net中将日期时间值存储在oracle中,当日期时间持续到db时,时间信息丢失。
db是11g,我正在使用Oracle.DataAccess程序集版本2.111.6.20中的OracleCommand和OracleConnection类。
我在.net中有一个调用oracle存储过程的数据层。有问题的日期字段的参数是IN参数,它是标记为TimeStamp数据类型。表中的字段也定义为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;
知道为什么时间戳会丢失时间信息吗?
答案 0 :(得分:2)
好的,我想我已经弄清楚问题是什么了。在上面的例子中,我从存储的proc中省略了一些额外的参数以用于berevity。我在查询中有其他参数,其中一些是数据类型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中的Parameters集合的顺序将决定存储过程中参数的值
所以,在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
答案 1 :(得分:0)
当你发出这个选择时,你看到了什么:
SELECT TO_CHAR(RECEIVED, 'MM/DD/YYYY HH24:MI:SS') FROM data WHERE ID = <value>;
答案 2 :(得分:0)
我将您的代码运行到一个表中,我的结果是(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
如果有的话,试试这样的东西,看它是否有效,然后回去检查你的程序,看看是否有什么东西看起来不合适(像一个任性的截断)
答案 3 :(得分:0)
如果使用的是Oracle提供的dll,则默认情况下它通常绑定变量。在执行以绑定到名称之前,添加以下代码行。
cmd.BindByName = true;