2016-11-28 6 views
0

TIMESTAMP(0) WITH TIMEZONEの列を持つ表の更新を試行しています。データベースのTIME ZONE値を使用してOracle TIMESTAMP(0)を更新する適切な方法

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ここ

多くの投稿は、それがデータベースから取得のデータをフォーマットに主に話します。他の例はC#ではなくSqlPlusで記述されています。

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#でこれを行うための適切な方法は何ですか?日付/タイムスタンプ列は常に文字列からの変換で書き込まれるべきですか?

答えて

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それはTimeStampTZでなければならない、Varchar2ではありません。

ただし、DevArtのOracle Data Providerを使用しているようです。 documentationをチェックすると、データタイプTIMESTAMP WITH TIME ZONEがサポートされていないように見えます。

いくつかの回避策があります。

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戻り、現在の時刻では、データベース上の操作を実行する前に、あなたのSESSIONTIMEZONE-05:00にを設定し、このように例えば

セッションのタイムゾーンはTIMESTAMP WITH TIME ZONEのデータタイプです。

あなたはまた、例えば、SQLで時間帯を指定することができます:あなたはタイムゾーン-05:00を使用してTIMESTAMP WITH TIME ZONEへの暗黙的なキャストを行いますTIMESTAMP OracleとTIMESTAMP WITH TIME ZONE値を更新

cmd.CommandText = "update customer set email_addr = :EMAIL, 
     modified_date= SYSTIMESTAMP AT TIME ZONE '-05:00' 
    where cust_id = :CUSTID"; 

、アメリカ/ニューヨークは夏時間を持っている、(あなたがAmerica/New_Yorkのようなタイムゾーンの領域を使用する場合には、偉大なBEFITだろう)あなたはこれらのコマンドは、よりダイナミックにし、年2回-05:00-04:00の間で切り替える必要があり、すなわち、 。

もう1つの回避策は、AMERICA/NEW_YORKのようなタイムゾーン名を処理できないアプリケーションでALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT = 'DD-MON-YY HH.MI:SS.FF AM TZH:TZM'を実行することです。

+0

これは私が必要としていたもので、セッションパラメータの設定に関する別の質問にも答えています。ありがとうございました!私はSYSTIMESTAMPを使用するときにBTWを自動的に正しいタイムゾーンを取得するので、実際には 'AT TIME ZONE'を使用する必要はありませんでした。ありがとうございました。 – Mobilemike

関連する問題