2012-03-16 229 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(); 
} 

...似乎工作(返回一個值,和插入的(貌似)無叫聲制)......到目前爲止,還沒有記錄插入到數據庫中。

這個缺憾(?SP)功能,OTOH:

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); 
} 

...工作正常 - 記錄插入到數據庫(即調用這些函數後面的代碼)。

這似乎很奇怪,他們都返回一個字符串,但一個工程,並沒有...該列沒有約束它是拒絕從前函數的值,所以......? ?

總之,這裏的調用其中的任意一種功能,在上下文中的代碼:

 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(); 
     } 

更新REDX:

盧克提出了使用兩個同時連接的好處;所以,我改變了這個代碼:

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; 
    } 
} 

......但在Mudville仍然沒有快樂。

更新REDX重新訪問:

我得到它的工作;感謝大家的幫助和見解。

實際上,它已經工作了一段時間 - 我在蟾蜍中的愚蠢查詢是問題 - 我忘記了我在新記錄中添加了一個稍微不同於我查詢的值的記錄...所以它看起來像記錄沒有' t被添加,但他們確實是。 tgif!

+0

您是否嘗試在SQLPLUS控制檯中運行SELECT命令? – 2012-03-16 22:22:30

+0

GetInterpreterTicketIDSequenceVal返回哪個字符串?你有沒有設置一個斷點來查看它返回的內容? – 2012-03-16 22:29:45

+0

由於假的方法據說使這項工作,我猜測發佈的代碼只是缺少代碼添加p_TICKETID參數到參數集合。但這可能與它有關。 – Corin 2012-03-16 22:31:48

回答

1

我試圖運行上面的代碼中,我是唯一能如果INTERPRETERTICKETID序列超過了999999,就會重現問題。如果遇到問題,那麼肯定有一些問題沒有告訴我們。例如,您的表INTERPRETERTICKET如何定義?它有什麼限制?如何定義序列?桌子上有觸發器嗎?

是否有任何需要您的GetInterpreterTicketIDSequenceVal()方法使用自己的連接到數據庫?它可以不只是使用相同的連接,你的代碼的其餘部分呢?

如果序列INTERPRETERTICKETID已經超越999999那麼TO_CHAR調用將返回散列的字符串:

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

LTRIM(T 
------- 
999999 

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

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

我把PK約束的TICKETID柱和運行代碼兩次之後,我有一個約束違規錯誤。

編輯

在回答您的意見,也可以使用觸發器來填充TICKETID列。你提到你的數據庫顯然包含一個這樣的觸發器,但沒有看到如何定義觸發器,很難知道它的問題可能是什麼。

我添加了下面的觸發器,並修改了C#代碼,以便它不嘗試爲TICKETID插入一個值。我跑了幾次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

我們沒有「標識符票」表;假設你的意思是INTERPRETERTICKETS。 該表的唯一限制實際上是該列,但它看起來無害:Type = Primary Key;狀態=啓用;可推遲=不可推遲;遞延=立即;已驗證=已驗證 有一個觸發器看起來像它自動爲該列生成值。這實際上是我期望會發生的事情,而我試圖添加記錄的第一個錯誤是該(PK)列未被添加...因此,我明確添加了該值。顯然你必須用Oracle序列來做到這一點。 – 2012-03-16 23:54:16

+0

@ClayShannon:對不起,表名錯誤,我現在修復了。可以使用觸發器自動生成列值。我編輯了我的答案以添加有關如何執行此操作的詳細信息。 – 2012-03-17 13:24:06

+0

我現在不在工作,所以不能訪問Toad /數據庫,但如果觸發器自動添加該val(有道理,他們會這樣設計),爲什麼它可以正常工作我的「假」功能?小馬克裏有東西爛了。 – 2012-03-17 21:27:47

1

的方式,您設置的參數看起來很奇怪,因爲你的參數對象最終沒有名字 - 嘗試改變類似於你的代碼這樣:

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

我改變了我的代碼風格,並沒有改變;我認爲我不需要參數明確命名的原因是,只要它們按照它們在查詢語句中出現的相同順序添加,它們就可以工作。 – 2012-03-16 23:14:56

+0

我懂了;感謝大家的幫助和見解。 實際上,它一直在工作 - 我在蟾蜍中的愚蠢查詢是問題 - 我忘記了我在新記錄中添加了一個稍微不同於我正在搜索的值...因此它看起來像記錄不是' t被添加,但他們確實是。 – 2012-03-17 00:22:34

相關問題