0

タイプ の列を持つテーブルを更新しようとしていますTIMESTAMP(0) WITH TIMEZONE

データベースへの書き込み方法には米国東部時間のTIMESTAMPようなオフセット形式がないため、いくつかの方法を試しましたが成功しませんでした。-05:00タイム ゾーンとして使用して保存AMERICA/NEW_YORKされるため、これを適切に処理できない別のアプリケーションで問題が発生します。

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

4

1 に答える 1

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 を使用しているようです。ドキュメントを確認すると、data type をサポートしていないよう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 ZONEOracle で値を更新すると、タイム ゾーンを使用TIMESTAMPするように暗黙的にキャストされます。TIMESTAMP WITH TIME ZONE-05:00

America/New_York には夏時間があることに注意-05:00してください。つまり、これらのコマンドをより動的にして、年に 2 回とを切り替える必要があります-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

于 2016-11-29T07:48:29.043 に答える