OdbcTransaction 与OdbcCommandBuilder的问题
环境:数据库:sybase ase15.03
开发工具:vs2012
自己的想法:写一个方法,将传人的DataTable 写入数据库中
遇到的困难及过程:
开始使用的是oledb连接,结果报“对于不返回任何键列信息的 SelectCommand 不支持 UpdateCommand 的动态 SQL 生成” 查资料说数据库无主键造成,而数据库确实是有主键,而返回的DataTable没有主键,估计是sybase 客户端原因,后来使用ODBC连接,传入的DataTable中的增加和删除能正常回写到数据库中,(修改未测),因为可能同时提交多个表,考虑使用事务来处理,于是修改了函数,结果增加可以,删除报“对于不返回任何键列信息的 SelectCommand,不支持 DeleteCommand 的动态 SQL 生成”,求帮助
代码:
public int UpdataTable(DataTable dt, string tableName, string Dbname)
{
OdbcConnection connect = new OdbcConnection(OledbToOdbcConnectString(GetConnectString(Dbname)));
OdbcDataAdapter da = new OdbcDataAdapter("select * from "+tableName + " where '1'='0'",connect );
connect.Open();
OdbcTransaction ot = connect .BeginTransaction ();//后修改的
da.SelectCommand.Transaction = ot;//后修改的
OdbcCommandBuilder ob = new OdbcCommandBuilder(da);
int i = da.Update(dt);
ot.Commit();//后修改的
connect.Close();
return i;
} --------------------编程问答-------------------- 在哪里报错?异常内容呢? --------------------编程问答-------------------- int i = da.Update(dt);
这句报错的
异常内容:对于不返回任何键列信息的 SelectCommand,不支持 DeleteCommand 的动态 SQL 生成 --------------------编程问答-------------------- 查不到数据吧。。。
你那sql语句不对吧。
where '1'='0'",???
这可以吗? --------------------编程问答-------------------- 这个不影响,不使用事务的时候可以的 --------------------编程问答-------------------- 知道了。事务是需要你commit的。commit一下。。
你这个还没有提交也就没取回数据呢。 --------------------编程问答-------------------- 你取数据干嘛要用事务呢?? --------------------编程问答-------------------- 明明是写,少爷,你看懂了不? --------------------编程问答-------------------- “对于不返回任何键列信息的 SelectCommand
你new个dataset,你看你能取出数据来? --------------------编程问答-------------------- 可以,在说下
OdbcTransaction ot = connect .BeginTransaction ();//后修改的
da.SelectCommand.Transaction = ot;//后修改的
ot.Commit();//后修改的
这个三条语句去掉后就正常的 --------------------编程问答-------------------- 现在已经用变通方法搞定,但是不明白报错原因,求大神解释
解决思路如下,
症状分析:不使用Transaction 的时候一切是正常,而使用了Transaction 后,在
int i = da.Update(dt);
报错,报错信息为“对于不返回任何键列信息的 SelectCommand,不支持 DeleteCommand 的动态 SQL 生成”,从此判断在自动生成DeleteCommand 的时候报错的,而不加Transaction 的时候是可以自动生成command的,于是用了一个变通方法,先不加Transaction,用GetDeleteCommand方法获得DeleteCommand ,然后再手工赋值给OdbcDataAdapter ,再加入Transaction ,按此方法实验后通过,
代码:
public int UpdataTable(DataTable dt, string tableName, string Dbname)
{
OdbcConnection connect = new OdbcConnection(OledbToOdbcConnectString(GetConnectString(Dbname)));
OdbcDataAdapter tempDa = new OdbcDataAdapter("select * from " + tableName + " where '1'='0'", connect);
OdbcCommandBuilder ob = new OdbcCommandBuilder(tempDa);
OdbcDataAdapter da = new OdbcDataAdapter("select * from " + tableName + " where '1'='0'", connect);
da.InsertCommand = ob.GetInsertCommand();
da.DeleteCommand = ob.GetDeleteCommand();
da.UpdateCommand = ob.GetUpdateCommand();
connect.Open();
OdbcTransaction ot = connect.BeginTransaction();
da.SelectCommand.Transaction = ot;
da.InsertCommand .Transaction = ot;
da.DeleteCommand .Transaction = ot;
da.UpdateCommand .Transaction = ot;
int i = da.Update(dt);
ot.Commit();
//ot.Rollback();
connect.Close();
return i;
}
虽然解决了,但是让人很不爽,求大神帮忙,这到底怎么回事 --------------------编程问答-------------------- 你好,我考虑你将selectcommand与其他三种,I,U,D,操作的Transaction分开,定义两个事务,selectcommand的事务在进行其他操作前先提交一次。原因猜测为,Selectcommand语句是自动生产语句的基础,先要提交执行一次让adapter获得相应的列信息,才能自动创建SQL语句。
补充:.NET技术 , C#