我正在尝试更新一个类型为TIMESTAMP(0) WITH TIMEZONE
的列的表。
我已经尝试了几种方法但没有成功,因为TIMESTAMP
写入数据库的方式没有美国东部时间的-05:00
等偏移格式。它使用AMERICA/NEW_YORK
作为时区进行保存,这会导致另一个无法正确处理此问题的应用程序出现问题。
CURRENT:28-NOV-16 10.51.43.000000000 AM AMERICA/NEW_YORK
希望:28-NOV-16 10.51.43.000000000 AM -05:00
这里的许多帖子主要是在从数据库中检索数据时格式化数据;其他示例用SqlPlus描述,而不是在C#中描述。
Using(OracleConnection conn = new OracleConnection(......))
{
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.BindByName = true;
cmd.CommandText = "update customer set email_addr = :EMAIL, modified_date= SYSDATE
where cust_id = :CUSTID";
conn.Open();
cmd.Parameters.Add("EMAIL", OracleDbType.Varchar2).Value = txtEmail.Text;
cmd.Parameters.Add("MODIFIED_DATE", OracleDbType.Varchar2).Value = OracleDate.GetSysDate().ToOracleTimeStamp();
cmd.Parameters.Add("CUSTID", OracleDbType.Decimal).Value =Convert.ToDecimal(Session["ID"]);
cmd.ExecuteNonQuery();
}
我也尝试了modified_date=to_timestamp(:modified_date, 'MM/DD/YYYY HH:mi:ss')
,但这会产生异常,因为时区格式不正确。
在C#中实现此目的的正确方法是什么?是否应始终使用字符串转换写入日期/时间戳列?
答案 0 :(得分:1)
看起来你在代码中输了一个错字。您指定了2个绑定变量,但尝试绑定3个值。
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.BindByName = true;
cmd.CommandText = "update customer set email_addr = :EMAIL, modified_date= :MODIFIED_DATE
where cust_id = :CUSTID";
conn.Open();
cmd.Parameters.Add("EMAIL", OracleDbType.Varchar2).Value = txtEmail.Text;
cmd.Parameters.Add("MODIFIED_DATE", OracleDbType.TimeStampTZ).Value = OracleDate.GetSysDate().ToOracleTimeStamp();
cmd.Parameters.Add("CUSTID", OracleDbType.Decimal).Value =Convert.ToDecimal(Session["ID"]);
cmd.ExecuteNonQuery();
OracleDbType
不是Varchar2
,必须是TimeStampTZ
。
但是,看起来您正在使用DevArt的Oracle Data Provider。当我检查documentation时,它们看起来不支持数据类型TIMESTAMP WITH TIME ZONE
。
我看到了几个解决方法。
在对数据库运行操作之前将SESSIONTIMEZONE
设置为-05:00
,例如:
cmd.CommandText = "ALTER SESSION SET TIME_ZONE = '-05:00'";
cmd.ExecuteNonQuery();
然后您的C#代码可以是这样的:
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.BindByName = true;
cmd.CommandText = "update customer set email_addr = :EMAIL, modified_date= CURRENT_TIMESTAMP
where cust_id = :CUSTID";
conn.Open();
cmd.Parameters.Add("EMAIL", OracleDbType.Varchar2).Value = txtEmail.Text;
cmd.Parameters.Add("CUSTID", OracleDbType.Decimal).Value =Convert.ToDecimal(Session["ID"]);
cmd.ExecuteNonQuery();
CURRENT_TIMESTAMP将会话时区中的当前时间作为TIMESTAMP WITH TIME ZONE
数据类型返回。
您还可以在SQL中指定时区,例如:
cmd.CommandText = "update customer set email_addr = :EMAIL,
modified_date= SYSTIMESTAMP AT TIME ZONE '-05:00'
where cust_id = :CUSTID";
当您使用TIMESTAMP WITH TIME ZONE
更新TIMESTAMP
值时,Oracle会使用时区TIMESTAMP WITH TIME ZONE
隐式转换为-05:00
。
注意,America / New_York有夏令时,即您必须使这些命令更具动态,并且每年在-05:00
和-04:00
之间切换两次(这将是如果您使用America/New_York
)等时区区域,那就太棒了。
另一种解决方法可能是在您的应用程序中运行ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT = 'DD-MON-YY HH.MI:SS.FF AM TZH:TZM'
,该AMERICA/NEW_YORK
无法处理jQuery(function() {
$('.abc').datetimepicker({
minDate: 0
});
});
等时区名称。