何时是字符串而不是字符串
本文关键字:字符串 何时 | 更新日期: 2023-09-27 18:28:15
来自"数据库引擎中的问题"部门:
此函数返回一个看起来有效的值,但没有发布记录(无错误消息):
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工作(返回一个值,插入(似乎)没有发出刺耳的声音)。。。然而,没有任何记录被插入到数据库中。
这种松散的(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();
}
更新redux:
卢克提出了一个很好的观点,即使用两个同时连接;所以,我把代码改成了这个:
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;
}
}
但在穆德维尔仍然没有快乐。
重新访问更新redux:
我让它工作;感谢大家的帮助和真知灼见。
事实上,它已经工作了一段时间——我在Toad中的愚蠢查询是问题所在——我忘记了我在新记录中添加的值与我查询的值略有不同……所以看起来这些记录没有被添加,但它们确实被添加了。tgif!
我试着运行上面的代码,只有当INTERPRETERTICKETID
序列超过999999时,我才能重现它的问题。如果您有问题,那么一定有一些事情没有告诉我们。例如,您的表INTERPRETERTICKET
是如何定义的?有什么限制?序列是如何定义的?桌子上有触发器吗?
您的GetInterpreterTicketIDSequenceVal()
方法是否需要使用自己与数据库的连接?它能不能不只是使用与其他代码相同的连接?
如果你的序列INTERPRETERTICKETID
已经超过999999,那么TO_CHAR
调用将返回一个散列字符串:
SQL>从dual中选择ltrim(to_char(999999,000000'));LTRIM(T-------999999SQL>从dual中选择ltrim(to_char(1000000,000000'));LTRIM(T-------#######
我在TICKETID
列上放置了一个PK约束,在运行您的代码两次后,我得到了一个违反约束的错误。
编辑:
为了响应您的评论,可以使用触发器填充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;
/
设置参数的方式似乎很奇怪,因为您的参数对象最终没有名称-尝试更改类似的代码:
OracleParameter p_TICKETID = new OracleParameter("p_TICKETID", OracleDbType.NVarchar2, ParameterDirection.Input);
p_TICKETID.Size = 20;