2012-03-16 8 views
1

次のとおりです。は場合、文字列でない文字列部門「データベースエンジンにバンプを行くこと」から

private String GetInterpreterTicketIDSequenceVal() 
{ 
    con = new OracleConnection(oradb); 
    con.Open(); 

    String query = "SELECT TO_CHAR(SYSDATE,'YYYYMMDD-') || LTRIM(TO_CHAR(ABC.SOMETABLEID.NEXTVAL, '000000')) FROM DUAL"; 

    cmd = new OracleCommand(query, con); 
    cmd.CommandType = CommandType.Text; 
    //MessageBox.Show(cmd.ExecuteScalar().ToString()); 
    return cmd.ExecuteScalar().ToString(); 
} 

...は、レコードがデータベースに挿入されていない、動作するように思われる(値を返し、挿入(一見)squawkingすることなくなされている)...まだ。

この場しのぎでは(?SP)機能、大藤:

private String GetSomeTableIDSequenceVal_Fake() 
{ 
    int iYear = DateTime.Now.Year; 
    int iMonth = DateTime.Now.Month; 
    int iDay = DateTime.Now.Day; 
    int iHour = DateTime.Now.Hour; 
    int iSecond = DateTime.Now.Second; 

    String sYear = iYear.ToString(); 
    String sMonth = iMonth.ToString(); 
    String sDay = iDay.ToString(); 
    String sHour = iHour.ToString(); 
    String sSecond = iSecond.ToString(); 

    if (iMonth < 10) 
    { 
     sMonth = String.Format("0{0}", sMonth); 
    } 
    if (iDay < 10) 
    { 
     sDay = String.Format("0{0}", sDay); 
    } 
    if (iHour < 10) 
    { 
     sHour = String.Format("0{0}", sHour); 
    } 
    if (iSecond < 10) 
    { 
     sSecond = String.Format("0{0}", sSecond); 
    } 

    return String.Format("{0}{1}{2}-{3}{4}", sYear, sMonth, sDay, sHour, sSecond); 
} 

...正常に動作します - レコードがデータベース(以下のこれらの関数を呼び出すコード)に挿入されています。

彼らの両方が文字列を返すことを奇妙に思える、まだ1つの作​​品、および1つは...その列は元の関数から値を拒否して、それに対する制約を持っているので...しませんしません? ?

はとにかく、ここではそれらの機能のいずれかを呼び出すコードは、コンテキストに、です:

 try 
     { 
      con = new OracleConnection(oradb); 
      con.Open(); 
      String query = "INSERT INTO ABC.SOMETABLE (TICKETID, TICKETSOURCE, ABOUTSOMEID, CATEGORYID, CONTACTEMAIL) VALUES (:p_TICKETID, :p_TICKETSOURCE, :p_ABOUTSOMEID, :p_CATEGORYID, :p_CONTACTEMAIL)"; 

      cmd = new OracleCommand(query, con); 
      cmd.CommandType = CommandType.Text; 

      // Params = TICKETID, TICKETSOURCE, ABOUTSOMEID, CATEGORYID, CONTACTEMAIL 
      OracleParameter p_TICKETID = new OracleParameter(); 
      p_TICKETID.Direction = ParameterDirection.Input; 
      p_TICKETID.OracleDbType = OracleDbType.NVarchar2; 
      p_TICKETID.Size = 20; 
      // This doesn't allow the record to be inserted...??? 
      //p_TICKETID.Value = GetSomeTableIDSequenceVal(); 
      // ...but when I "fake it" below, the record IS inserted 
      //p_TICKETID.Value = GetSomeTableIDSequenceVal_Fake();    cmd.Parameters.Add(p_TICKETID); 

      OracleParameter p_TICKETSOURCE = new OracleParameter(); 
      p_TICKETSOURCE.Direction = ParameterDirection.Input; 
      p_TICKETSOURCE.OracleDbType = OracleDbType.NVarchar2; 
      p_TICKETSOURCE.Size = 20; 
      p_TICKETSOURCE.Value = textBoxTicketSource.Text; 
      cmd.Parameters.Add(p_TICKETSOURCE); 

      OracleParameter p_ABOUTSOMEID = new OracleParameter(); 
      p_ABOUTSOMEID.Direction = ParameterDirection.Input; 
      p_ABOUTSOMEID.OracleDbType = OracleDbType.Int32; 
      p_ABOUTSOMEID.Value = textBoxAboutSOMEID.Text; 
      cmd.Parameters.Add(p_ABOUTSOMEID); 

      OracleParameter p_CATEGORYID = new OracleParameter(); 
      p_CATEGORYID.Direction = ParameterDirection.Input; 
      p_CATEGORYID.OracleDbType = OracleDbType.Int32; 
      p_CATEGORYID.Value = textBoxCategoryID.Text; 
      cmd.Parameters.Add(p_CATEGORYID); 

      OracleParameter p_CONTACTEMAIL = new OracleParameter(); 
      p_CONTACTEMAIL.Direction = ParameterDirection.Input; 
      p_CONTACTEMAIL.OracleDbType = OracleDbType.NVarchar2; 
      p_CONTACTEMAIL.Size = 100; 
      p_CONTACTEMAIL.Value = textBoxContactEmail.Text; 
      cmd.Parameters.Add(p_CONTACTEMAIL); 

      try 
      { 
       cmd.ExecuteNonQuery(); 
      } 
      catch (OracleException ex) 
      { 
       MessageBox.Show(ex.Message); 
      } 
      MessageBox.Show("Apparent success"); 
     } 
     finally 
     { 
      con.Close(); 
      con.Dispose(); 
     } 

アップデート:

私はXactionのサポートを追加し、全く違いはありませんようだ:

私はトランザクションでそれを封入しており、違いはありません:

OracleTransaction ot; 
     . . . 
     try 
     { 
      ot = con.BeginTransaction(); 
      cmd.Transaction = ot; 
      cmd.ExecuteNonQuery(); 
      ot.Commit(); 
     } 
     catch (Exception ex) 
     { 
      ot.Rollback(); 
     } 

更新Reduxの:

ルークは、2つの同時接続を使用についての良い点を作りました。だから、私はこのコードを次のように変更しました:

private String GetInterpreterTicketIDSequenceVal() 
{ 
    String query = "SELECT TO_CHAR(SYSDATE,'YYYYMMDD-') || LTRIM(TO_CHAR(ABC.SOMETABLEID.NEXTVAL, '000000')) FROM DUAL"; 

    OracleCommand oc = new OracleCommand(query, con); 
    oc.CommandType = CommandType.Text; 
    String s = oc.ExecuteScalar().ToString(); 
    try 
    { 
     return s; 
    } 
    catch (OracleException ex) 
    { 
     MessageBox.Show(ex.Message); 
     return string.Empty; 
    } 
} 

...しかし、まだマッドビルでは喜びはありません。

更新待ち再入力:

私はそれを稼働させました。あなたの助けと洞察力に感謝します。

実際、Toadの私の愚かなクエリが問題だったのですが、新しいレコードには私が照会していたものと少し異なる値を追加していたことを忘れていました。追加されたが、彼らは本当にあった。 tgif!

+0

SQLPLUSコンソールでSELECTコマンドを実行しようとしましたか? –

+0

'GetInterpreterTicketIDSequenceVal'はどの文字列を返しますか?それが返すものを見るためにブレークポイントを設定しましたか? –

+0

偽のメソッドはおそらくこの作業をしているので、投稿されたコードは、p_TICKETIDパラメータをパラメータコレクションに追加するコードが不足していると推測しています。しかし、それはそれと関係しているかもしれません。 – Corin

答えて

1

私は上記のコードを実行しようとしたと私はにのみことができましたINTERPRETERTICKETIDのシーケンスが999999を超えた場合は、問題を再現してください。問題が発生した場合は、私たちに何も言わないでください。たとえば、テーブルINTERPRETERTICKETはどのように定義されていますか?どのような制約がありますか?シーケンスはどのように定義されていますか?テーブルにトリガーがありますか?

データベースへの独自の接続を使用するようにGetInterpreterTicketIDSequenceVal()方法の必要性はありますか?残りのコードと同じ接続を使用できるだけではありませんか?

あなたの順序INTERPRETERTICKETIDは、TO_CHAR呼び出しはハッシュの文字列を返します999999を超えてしまった場合:

 
SQL> select ltrim(to_char(999999, '000000')) from dual; 

LTRIM(T 
------- 
999999 

SQL> select ltrim(to_char(1000000, '000000')) from dual; 

LTRIM(T 
------- 
####### 

私はTICKETID列にPK制約を入れて、二回あなたのコードを実行した後、私は制約を得ました違反エラー。

EDIT

あなたのコメントを受けて、TICKETID列を移入するためにトリガーを使用することが可能です。あなたのデータベースに明らかに1つのそのようなトリガが含まれていると述べましたが、トリガがどのように定義されているかを見ることなく、その問題が何であるかを知ることは困難です。

次のトリガーを追加し、TICKETIDの値を挿入しようとしないようにC#コードを変更しました。私は数回C#コードを実行し、それは動作するように見えました。

CREATE OR REPLACE TRIGGER INTERPRETERTICKETS_BI 
    BEFORE INSERT ON INTERPRETERTICKETS 
    FOR EACH ROW 
BEGIN 
    SELECT TO_CHAR(SYSDATE,'YYYYMMDD-') || LTRIM(TO_CHAR(INTERPRETERTICKETID.NEXTVAL, '000000')) 
    INTO :new.TICKETID 
    FROM DUAL; 
END; 
/
+0

"Identifier Ticket"テーブルはありません。あなたが解釈指数を意味すると仮定します。 テーブルの唯一の制約は、実際にはその列に対してですが、無害です。Type = Primary Key;ステータス=有効。繰延可能=繰延可能ではありません。遅延=即時; Validated = Validated 自動的にその列の値を生成するようなトリガーがあります。これは実際に起こりそうなことですが、レコードを追加しようとする最初のエラーは、(PK)列が追加されていないということでした...だから、値を明示的に追加しました。明らかに、Oracle Sequencesを使用してこれを実行する必要があります。 –

+0

@ClayShannon:テーブル名を間違えてしまって申し訳ありませんが、今修正しました。トリガーを使用して列値を自動的に生成することは可能です。私はそれを行う方法の詳細を追加するために私の答えを編集しました。 –

+0

私は仕事に就いていないので、Toad /データベースへのアクセス権がありませんが、トリガーがそのvalを自動的に追加している場合(そのように設計するのは理にかなっています)私の "偽の"機能?デンマークで腐ったもの –

1

あなたのパラメータオブジェクトは、名前なしで終わるので、セットアップパラメータを方法は非常に奇妙なようだ - これに似たコードを変更してみてください:

OracleParameter p_TICKETID = new OracleParameter("p_TICKETID", OracleDbType.NVarchar2, ParameterDirection.Input); 
p_TICKETID.Size = 20; 
+0

私のコードをそのスタイルに変更しました。変更はありません。私は、paramsに明示的に名前を付ける必要はないという理由は、クエリステートメントに表示される順序と同じ順序で追加されていれば、機能するということです。 –

+0

私はそれを働かせました。あなたの助けと洞察力に感謝します。 実際にはToadの私の愚かなクエリが問題だったのですが、私が検索していたものとは少し違った値を新しいレコードに追加していたことを忘れてしまったので、追加されたが、彼らは本当にあった。 –

関連する問題