当是一个字符串不是一个字符串
从“的事,去凹凸数据库引擎”部门:当是一个字符串不是一个字符串
这个函数返回什么看起来像一个有效的价值,但记录不贴(没有错误消息):
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!
我试图运行上面的代码中,我是唯一能如果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;
/
我们没有“标识符票”表;假设你的意思是INTERPRETERTICKETS。 该表的唯一限制实际上是该列,但它看起来无害:Type = Primary Key;状态=启用;可推迟=不可推迟;递延=立即;已验证=已验证 有一个触发器看起来像它自动为该列生成值。这实际上是我期望会发生的事情,而我试图添加记录的第一个错误是该(PK)列未被添加...因此,我明确添加了该值。显然你必须用Oracle序列来做到这一点。 – 2012-03-16 23:54:16
@ClayShannon:对不起,表名错误,我现在修复了。可以使用触发器自动生成列值。我编辑了我的答案以添加有关如何执行此操作的详细信息。 – 2012-03-17 13:24:06
我现在不在工作,所以不能访问Toad /数据库,但如果触发器自动添加该val(有道理,他们会这样设计),为什么它可以正常工作我的“假”功能?小马克里有东西烂了。 – 2012-03-17 21:27:47
的方式,您设置的参数看起来很奇怪,因为你的参数对象最终没有名字 - 尝试改变类似于你的代码这样:
OracleParameter p_TICKETID = new OracleParameter("p_TICKETID", OracleDbType.NVarchar2, ParameterDirection.Input);
p_TICKETID.Size = 20;
我改变了我的代码风格,并没有改变;我认为我不需要参数明确命名的原因是,只要它们按照它们在查询语句中出现的相同顺序添加,它们就可以工作。 – 2012-03-16 23:14:56
我懂了;感谢大家的帮助和见解。 实际上,它一直在工作 - 我在蟾蜍中的愚蠢查询是问题 - 我忘记了我在新记录中添加了一个稍微不同于我正在搜索的值...因此它看起来像记录不是' t被添加,但他们确实是。 – 2012-03-17 00:22:34
您是否尝试在SQLPLUS控制台中运行SELECT命令? – 2012-03-16 22:22:30
GetInterpreterTicketIDSequenceVal返回哪个字符串?你有没有设置一个断点来查看它返回的内容? – 2012-03-16 22:29:45
由于假的方法据说使这项工作,我猜测发布的代码只是缺少代码添加p_TICKETID参数到参数集合。但这可能与它有关。 – Corin 2012-03-16 22:31:48