From the “Things that go bump in the database engine” department:
This function returns what looks like a valid value, but the record is not posted (no err msg):
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();
}
…SEEMS to work (returns a value, and the insertion is (seemingly) made without squawking)… yet, no record is inserted into the database.
This kludgy (sp?) function, 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);
}
…works fine – the record is inserted into the database (the code that calls these functions follows).
It seems odd that they both return a string, yet one works, and one doesn’t… that column doesn’t have a constraint on it that is rejecting the value from the former function, so…???
Anyway, here’s the code that calls either of those functions, in context:
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();
}
Update:
I added Xaction support, and it seems to make no difference whatsoever:
I encased it in a Transaction, and it makes no difference:
OracleTransaction ot;
. . .
try
{
ot = con.BeginTransaction();
cmd.Transaction = ot;
cmd.ExecuteNonQuery();
ot.Commit();
}
catch (Exception ex)
{
ot.Rollback();
}
Update redux:
Luke made a good point about using two simultaneous connections; so, I changed that code to this:
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;
}
}
…but still no joy in Mudville.
Update redux revisited:
I got it working; thanks everybody for your help and insight.
Actually, it had been working for awhile – my stupid query in Toad was the problem – I forgot that I was adding a slightly different value in new records than what I was querying for … so it looked like the records weren’t being added, but they really were.
tgif!
I tried running your code above and I was only able to reproduce problems with it if the
INTERPRETERTICKETIDsequence had gone beyond 999999. If you are having problems then there must be something that you are not telling us. For example, how is your tableINTERPRETERTICKETdefined? What constraints are on it? How is the sequence defined? Are there any triggers on the table?Is there any need for your
GetInterpreterTicketIDSequenceVal()method to use its own connection to the database? Can it not just use the same connection that the rest of your code does?If your sequence
INTERPRETERTICKETIDhas gone beyond 999999 then theTO_CHARcall will return a string of hashes:I put a PK constraint on the
TICKETIDcolumn and after running your code twice, I got a constraint violation error.EDIT:
In response to your comment, it is possible to use a trigger to populate the
TICKETIDcolumn. You mentioned that your database apparently contains one such trigger, but without seeing how the trigger is defined, it’s difficult to know what the problem with it could be.I added the following trigger, and modified the C# code so that it didn’t attempt to insert a value for TICKETID. I ran the C# code a few times and it seemed to work.