SqlDataAdapter.SelectCommand не возвращает правильный результат - PullRequest
0 голосов
/ 18 февраля 2020

У меня просто проблема с моим кодом.

Я хочу выбрать некоторые данные из базы данных, используя свойство 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 все существующие строки в моей таблице базы данных будут возвращены. Что я здесь скучаю?

1 Ответ

0 голосов
/ 20 февраля 2020

Что касается блоков кода go, то, вероятно, справедливо будет сказать, что для этого нужно много работы. Почти в каждой линии есть что-то, что может использовать некоторое улучшение, но сама концепция, которую она воплощает, довольно нежелательна, потому что это по своей сути огромный риск для безопасности. Вот немного улучшенная версия:

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

Да; весь код, который вы написали, сводится к четырем строкам. Это все еще огромная проблема, когда вы просто бросаете строку с предложением where. Единственный способ избежать этого с помощью этого подхода - начать разбивать строку where на набор классов предикатов, sql внедрение защищено на уровне столбца и оператора и добавить значения в коллекцию SqlParameterCollection - это, по сути, сводит имеет собственную библиотеку доступа к данным и не стоит беспокоиться, учитывая, что многие десятки людей уже сделали это (включая microsoft)

Попробуйте вместо этого уйти от этой ужасной кроличьей норы, не делая вашего доступа к данным таким способом. Бросьте все это в tra sh и используйте вместо него Dapper . Это не большая кривая обучения, из которой вы сейчас находитесь, и она сделает все более безопасным, безопасным и простым в использовании способом


Как примечание к предложению WHERE, которое вы говорите в комментариях что вы используете:

WHERE DATEDIFF(day, sale_date, GetDate()) >= 365 AND available=1

Не делайте этого тоже. Здесь вы выполняете функцию операции по вводу данных в таблицу. Если ваша таблица содержит миллион дат, эту функцию нужно будет вызывать миллион раз. Он очень медленный, использует огромное количество ресурсов и наносит вред использованию индексов. И это совершенно не нужно. Вы ищете все продукты, проданные более года go? Рассчитайте ОДНУ ДАТУ какой даты это был год go и используйте SALE_DATE из сказки без каких-либо изменений по сравнению с ней:

-- in your sql
WHERE sale_date < @someDate and available = 1

//in your c#
mySqlCommand.Parameters.AddWithValue("@someDate", DateTime.UtcNow.AddYears(-1));

Видите разницу? Здесь c# вычисляет дату один раз и предоставляет ее в качестве параметра постоянного значения для запроса. В таблице с миллионами дат выполняется только одно простое сравнение. Мы не вычисляем, сколько дней было go миллионов различных дат, а затем выбираем только эти различия> 365

...