SqlDataAdapter.SelectCommand没有返回正确的结果

问题描述 投票:0回答:1

我只是遇到我的代码问题。

我想使用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中将返回数据库表的所有现有行。我在这里想念什么?

c# dataset sqlcommand sqldataadapter
1个回答
0
投票

就代码块而言,可以公平地说一个人需要做很多工作。几乎每条线都有可以改进的地方,但是它所体现的整个概念是相当令人反感的,因为它本质上是巨大的安全风险。这是一个略有改进的版本:

//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

© www.soinside.com 2019 - 2024. All rights reserved.