我想通过C#中的OdbcCommand对象一次执行MySql查询以下作为动态查询,它总是失败:
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
set @row=0;
select * from
(
select @row:=@row+1 as my____row_num,
cities.`cityid`,
cities.`cityname`,
cities.`countryid`,
cities.`countryname` , '1' as my____data_row_created , '1' as
my____data_row_updated from `cities` ) p
where my____row_num>=101 and my____row_num<=200;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ ;
我使用以下方法执行上述MySql查询:
ExcuteCommand(Sql)
{
DataTable dt = new DataTable();
OdbcCommand SQLCommand = new OdbcCommand(Sql);
OdbcConnection Con = new OdbcConnection(ConnectionString);
try
{
Con.Open();
SQLCommand.Connection = Con;
OdbcDataAdapter da = new OdbcDataAdapter(SQLCommand);
da.Fill(dt);
Con.Close();
Con.Dispose();
}
catch
{
try
{
Con.Close();
}
catch { }
throw;
}
return dt;
}
答案 0 :(得分:1)
我不打算尝试解决你的MySql问题(几乎所有我的SQL都是SQL Server的),但你的c#代码可以而且应该写得更好,而且由于评论不适合代码,我想我最好把它写成答案,(冒着被低估并被标记为非答案的风险)。
所以这是对你的c#部分的改进:
DataTable FillDataTable(string Sql)
{
var dataTable = new DataTable();
using(var con = new OdbcConnection(ConnectionString))
{
using(var command = new OdbcCommand(Sql, con))
{
using(var dataAdapter = new OdbcDataAdapter(SQLCommand))
{
dataAdapter.Fill(dataTable);
}
}
}
return dataTable;
}
兴趣点:
我已将您的方法重命名为更具描述性的名称。 ExecuteCommand
没有说明此方法的作用。 FillDataTable
是不言自明的。
using
语句确保处理实现IDisposable
接口的实例 - 几乎所有ADO.Net类都在实现它。
处理OdbcConnection也会将其关闭,因此您无需自己明确关闭它。
如果你没有对它们做任何事情,就没有必要捕捉异常。拇指规则是throw early, catch late.(实际上,只要您可以执行某些操作,例如写入日志,向用户显示消息,重试等等)。
DataAdapters隐式打开Connection对象,无需显式打开它。
您可以做的其他两项改进是:
此方法也接受参数。
此方法也接受CommandType
作为参数(目前,使用存储过程不起作用,因为CommandType
的默认值为Text
所以,更好的版本是:
DataTable FillDataTable(string Sql, CommandType commandType, params OdbcParameter[] parameters)
{
var dataTable = new DataTable();
using(var con = new OdbcConnection(ConnectionString))
{
using(var command = new OdbcCommand(Sql, con))
{
command.CommandType = commandType;
command.Parameters.AddRange(parameters);
using(var dataAdapter = new OdbcDataAdapter(SQLCommand))
{
dataAdapter.Fill(dataTable);
}
}
}
return dataTable;
}
如果你想进一步改进,你可以查看我的GitHub ADONETHelper项目 - 我有一个Execute
的私有方法,以及填充数据表的方法,填充数据集,执行非查询等都使用这种方法。
答案 1 :(得分:1)
我从here找到了解决方案。在C#中通过ODBC执行多个动态MySql语句时,我们有两个选择:
在我的情况下,我一定会使用动态quire,因为我只对数据库进行读访问。
<强>解决方案:强> 我使用另一种技术将会话变量用作派生表,并将其与主表交叉连接,而不是声明变量并设置它。请参阅以下查询,在我的方案中,我更改为MySql查询代码,并从查询中删除了两个SET SESSION相关代码,并且它正常工作:
select * from
(
select @row:=@row+1 as my____row_num,
cities.`cityid`,
cities.`cityname`,
cities.`countryid`,
cities.`countryname` , '1' as my____data_row_created , '1' as
my____data_row_updated from `cities` ,(select @row:=0) as t ) p
where my____row_num>=101 and my____row_num<=200;
答案 2 :(得分:0)
请你试试这个
declare @row int
set @row=0;
select * from
(
select SUM(@row,1) as my____row_num,
cities.cityid as CityID,
cities.cityname as CityName,
cities.countryid as CountryID,
cities.countryname as CountryName ,
'1' as my____data_row_created , '1' as my____data_row_updated from cities) //i did not understand the meaning of this
where (my____row_num BETWEEN 100 AND 200 )
ExcuteCommand(Sql)
{
<AddThis>ConnectionString= ConfigurationManager.ConnectionStrings["YourDataBaseLocation_OR_theConnectionCreatedViaProperties"].Connectionstring;</AddThis>
DataTable dt = new DataTable();
<deleteThis> OdbcCommand SQLCommand = new OdbcCommand(Sql);</deletethis>
//You Need to add the connection you have used it and Odbc
//Command.CommandType= CommandType.StoredProcedure();
OdbcConnection Con = new OdbcConnection(ConnectionString);
<AddThis>OdbcCommand SqlCommand = new OdbcCommand(Sql,Con);</AddThis>
try
{
Con.Open();
SQLCommand.Connection = Con;
OdbcDataAdapter da = new OdbcDataAdapter(SQLCommand);
da.Fill(dt);
<add this > SQLCommand.ExecuteNonQuery();</Add this>
Con.Close();
<delete> Con.Dispose();</delete>
}
catch
{
try
{
Con.Close();
}
catch (Exception e) { }
throw (e);
}
return dt;
}