我只是遇到我的代码问题。
我想使用SqlDataAdapter SelectCommand属性从数据库中选择一些数据。
我的代码如下:
static SqlConnection sqlConnection;
static SqlDataAdapter daDBData = new SqlDataAdapter();
static SqlCommand command = new SqlCommand();
static DataSet dsDBData = new DataSet("DBData");
static DataTable tblDBData;
static DataRow drCurrent;
public static DataTable dbDataGet(string tabname, string where)
{
sqlConnection = dbConnect(); //sqlConnection setup working fine, defined in another method
string helper = "SELECT * FROM " + tabname + where;
command = new SqlCommand(helper, sqlConnection);
daDBData.SelectCommand = command;
daDBData.MissingSchemaAction = MissingSchemaAction.AddWithKey;
daDBData.Fill(dsDBData, tabname);
tblDBData = dsDBData.Tables[tabname];
return tblDBData;
}
我的问题是,在tblDBData
中将返回数据库表的所有现有行。我在这里想念什么?
就代码块而言,可以公平地说一个人需要做很多工作。几乎每条线都有可以改进的地方,但是它所体现的整个概念是相当令人反感的,因为它本质上是巨大的安全风险。这是一个略有改进的版本:
//Don't need any of those static variables. Stop making everything static..
//In a properly structured C# program almost NOTHING should be declared as static
//Method names in C# use PascalCase convention, not camelCase
public DataTable DbDataGet(string tableName, string whereClause)
{
//this could be a massive security risk if there is any way at all that the
//user can influence the contents of the whereClause. DON'T DO IT if they can
SqlDataAdapter da = new SqlDataAdapter(
$"SELECT * FROM {tableName} WHERE {whereClause}",
GetConnectionString() //in this simplistic context, get a string, not a SqlConnection, then you don't handle disposal
);
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}
是的;您编写的所有代码可以归结为4行。只是将一个带有where子句的字符串扔掉仍然是一个很大的问题。使用这种方法可以避免这种情况的唯一方法是开始将where字符串分成一组谓词类,在列和运算符级别保护sql注入,然后将值添加到SqlParameterCollection-本质上是在滚动自己的数据访问库,因此不值得打扰,因为已经有很多人(包括Microsoft)完成了它]
请考虑完全不通过这种方式进行数据访问,从而摆脱这个可怕的困境。将其全部扔进垃圾桶,然后使用Dapper。从现在开始,这并不是一个巨大的学习曲线,并且将以一种更安全,更安全且更易于使用的方式来完成所有工作]
作为关于WHERE子句的注释,您在使用的注释中说:
WHERE DATEDIFF(day, sale_date, GetDate()) >= 365 AND available=1
也不要这样做。在这里,您可以对表中的数据条目执行功能操作。如果表中有一百万个日期,则该函数将需要调用一百万次。速度太慢了,消耗了大量资源,并削弱了索引的使用。而且这完全没有必要。您是否正在寻找所有销售超过一年的产品?计算一年前的一个日期,并使用故事中的SALE_DATE
,与之相比没有任何变化:
-- in your sql
WHERE sale_date < @someDate and available = 1
//in your c#
mySqlCommand.Parameters.AddWithValue("@someDate", DateTime.UtcNow.AddYears(-1));
看到区别了吗?在这里,c#仅计算一次日期,并将其作为常量值参数提供给查询。在一百万个日期的表中,仅执行一个简单比较。我们不计算多少天前一百万个不同的日期,然后仅选择那些差异> 365