2012-03-16 227 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

相关问题