有一段时间我正在处理oracle和.net,它们似乎并不完美匹配。这是奇怪的事情,我没有找到任何理由为什么会发生或如何解决它。
我做简单的插入,更新和删除,但它们无法正常工作。
失败了cmd.ExecuteNonQuery();
这是一段代码:
sqlCommand = string.Format(@" INSERT INTO TABLE_1
(ID, NAME, DESCRIPTION)
VALUES ((SELECT MAX(ID)+1 FROM TABLE_1),'{0}','{1}')", name, description);
using (OracleConnection conn = new OracleConnection(connectionString))
{
OracleCommand cmd = new OracleCommand(sqlCommand, conn);
cmd.CommandType = commandType;
try
{
conn.Open();
result = cmd.ExecuteNonQuery();
}
catch (Exception ex) { throw;}
finally
{
conn.Close();
}
一个简单的插入,对吧?!当我调试时,我得到cmd.Text值(这将是sqlCommand),我确实在oracle db中执行它,它就好了。当我在.Net中执行它时,它放弃了。
这是一个众所周知的情况吗?有没有解决方案,有什么解释吗?
Thnx提前
答案 0 :(得分:1)
这与你的问题无关,但是:
您应该使用序列而不是选择 (SELECT MAX(ID)+1 FROM TABLE_1)生成id
答案 1 :(得分:1)
我认为你的桌子被某人锁定了。或者表是否有位图索引?位图索引不应该在多个用户同时变异数据的环境中使用,因为它们会锁定很多。在oltp环境中使用BTree索引。
这与你的问题无关,但是:
使用Oracle时,必须使用参数化查询而不是string.Format(.. {} ...)。参数化查询要快得多,因为这意味着Oracle不必解析每个sql语句。
并执行类似
的操作create sequence table_1_seq
insert into table_1 (id, , ) values (table_1_seq.nextval, , )
填写内容。
而不是
(SELECT MAX(ID)+1 FROM TABLE_1)
因为它在多用户环境中不起作用。
修改1
您可以运行此选择以查明是否存在位图索引:
select index_name,table_name from all_indexes
where index_type = 'BITMAP';
答案 2 :(得分:0)
嗯,我想我刚刚得出了一个合理的解释:
数据库本应该忙着做另一次更新删除或插入操作,所以你无限期地等待它从应用程序进行更新。
我也有你的问题。我的问题是:
我们怎样才能避免这种等待,或者从数据库中获取消息“我在后面尝试”,以便用户知道会发生什么?
答案 3 :(得分:0)
取决于你是怎么做的;你可以使用:
catch (Exception ex)
{
System.Data.OracleClient.OracleException oEx = (System.Data.OracleClient.OracleException)ex.InnerException;
if (oEx.Message.IndexOf("ORA-0054") != 0)
{
.... do something here...
}
..将检测是否发生了锁定。 YMMV虽然我只在Oracle 9i上使用过它。
答案 4 :(得分:0)
我遇到了同样的问题。我不知道如何解决它。当我运行程序wihout sqldeveloper运行它就好了。我对这个问题的回答:关闭任何其他使用从计算机连接到oracle的程序。它对我来说很好。
答案 5 :(得分:0)
插入:
insert into student values('rahul',474,'mca','phase2');
删除:
delete from student where roll_no=472;
更新
update student set address='phase7' where roll_no=474;
答案 6 :(得分:-1)
提交Oracle客户端中使用的任何查询,如Toad或SQL-Developer
并行使用oracle客户端(如Toad或sSQL-Developer)和.net是不允许的,如果你想并行使用,那么在使用.net之前在oracle客户端使用commit。
然后尝试使用.net - 这将有效。