Не задано значение для одного или нескольких обязательных параметров с OleDBDataAdapter.

Привет всем, я понимаю, что этот вопрос задавался раньше, но даже если я буду следовать ответам, я все еще не могу заставить свой код работать. Ошибка возникает в «data_adapter.Fill (temp_table)», любая помощь в том, что происходит, будет оценена по достоинству.

string ConnStr = "Provider = Microsoft.Jet.OLEDB.4.0; Data Source = H:\\School Work\\Computing A Level\\Stock checker\\Program\\Morgan's Motors Database.mdb";

string Query = "SELECT * FROM [Car Info] WHERE @x ";
string FirstQuery = null;

int i = 0;

for (i = 0; i < ColumnName.Count - 1; i++)
{
    FirstQuery += string.Format("{0} = {1} AND ", ColumnName[i], EnteredFields[i]);
}

FirstQuery += string.Format("{0} = {1}", ColumnName[i], EnteredFields[i]);

MessageBox.Show(Query);

OleDbConnection database_connection = new OleDbConnection(ConnStr);

OleDbCommand database_command = new OleDbCommand(Query, database_connection);
database_command.Parameters.AddWithValue("@x", FirstQuery);

OleDbDataAdapter database_adapter = new OleDbDataAdapter();
database_adapter.SelectCommand = new OleDbCommand(database_command.CommandText, database_connection);

DataTable temp_table = new DataTable();

database_adapter.Fill(temp_table);

BindingSource data_source = new BindingSource();

data_source.DataSource = temp_table;

dataGridView1.DataSource = data_source;

РЕДАКТИРОВАТЬ: я добился некоторого прогресса в реструктуризации кода, теперь проблема в том, что "?" не заменяется

string ConnStr = "Provider = Microsoft.ACE.OLEDB.12.0; Data Source = H:\School Work\Computing A Level\Stock checker\Program\Morgan's Motors Database.mdb;";

            OleDbConnection conn_database = new OleDbConnection();
            conn_database.ConnectionString = ConnStr;

            OleDbCommand comm_database = new OleDbCommand();
            comm_database.CommandText = "SELECT * FROM [Car Info] WHERE ? = ?";
            comm_database.Connection = conn_database;

            OleDbDataAdapter adap_database = new OleDbDataAdapter(comm_database);

            DataTable data_database = new DataTable();

            for (int i = 0; i < ColumnName.Count; i++)
            {
                comm_database.Parameters.AddWithValue("?", ColumnName[i].ToString());
                comm_database.Parameters.AddWithValue("?", EnteredFields[i].ToString());

                MessageBox.Show(adap_database.SelectCommand.CommandText);

                adap_database.Fill(data_database);
            }

            BindingSource bind_database = new BindingSource();
            bind_database.DataSource = data_database;

            dataGridView1.DataSource = bind_database;

person HuwF    schedule 19.04.2013    source источник
comment
Вы не должны использовать манипуляции со строками для создания запросов - это подвергает вас атакам SQL-инъекций. Вместо этого используйте параметры.   -  person John Saunders    schedule 19.04.2013


Ответы (1)


Ты пробовал :

database_command.Parameters.AddWithValue("@x", EnteredFields[i]);

вместо :

database_command.Parameters.AddWithValue("@x", FirstQuery); 

Обычно при работе с параметром вы можете просто добавить имя параметра и его значение, а не добавлять columnName = к значению. Есть смысл?

Одна вещь, которую вы можете попробовать, если хотите использовать параметры, — это код ниже. Я не знаю, решит ли это вашу проблему или нет, но, по крайней мере, это поможет защитить вас от атак SQL Injection. Пожалуйста, дай мне знать, если возникнут какие-либо вопросы.

string Query = "SELECT * FROM [Car Info] WHERE {0} ";

for (i = 0; i < ColumnName.Count - 1; i++)
{
    FirstQuery += string.Format("{0} = @{1} AND ", ColumnName[i], ColumnName[i]);
}
FirstQuery += string.Format("{0} = @{1}", ColumnName[i], ColumnName[i]);
Query = String.Format(Query, FirstQuery);

for (i = 0; i < ColumnName.Count - 1; i++)
{
    database_command.Parameters.AddWithValue("@" + ColumnName[i], EnteredFields[i]);
}
person Erik Volkening    schedule 19.04.2013
comment
Я понимаю, что вы имеете в виду, я думаю, что мне нужно было быть немного яснее в моем первом посте. Введенный запрос зависит от количества параметров, введенных пользователем, например, пользователь в одном запросе может искать только CarID, но в другом он ищет CarID, производителя и модели, что означает, что мне нужны параметры запроса в той же переменной, если я сделайте цикл for, чтобы добавить их по одному, что, я не уверен, сработает. Но спасибо за помощь! - person HuwF; 19.04.2013
comment
Следующим моим предположением будет то, что одно из значений EnteredFields пустое. Таким образом, ваша строка FirstQuery может выглядеть так: CarId = AND MakeId = 1234. - person Erik Volkening; 19.04.2013
comment
Хорошо, сейчас я вставлю куда-нибудь MessageBox, чтобы проверить эту идею. - person HuwF; 19.04.2013
comment
Нет, они все есть при вводе информации. Может ли это быть как-то связано с типами данных, вводимых в запрос? CarID — это целое число, в то время как другие элементы, такие как Производитель и Модель, являются текстовыми. Я думал об этом раньше, но я не уверен, как это исправить - person HuwF; 19.04.2013
comment
Я считаю, что Access выдает упомянутую выше ошибку, когда возникают ошибки преобразования типа данных. Целые числа и логические значения в операторах типа SQL не нужно заключать в кавычки. пример: CarId = 1234 действителен. Поля строкового типа и гиды. пример: Сделать = 'значение'. Обычно вы можете полагаться на коллекцию параметров, чтобы отформатировать это для вас, но то, как вы используете предложение where, я догадываюсь, что этого не происходит. - person Erik Volkening; 19.04.2013
comment
Я знал о соглашениях об именах для строк, добавляя ' вокруг них, что я делаю, когда собираю их из текстовых полей. Я все еще думаю, что это ошибка преобразования типа данных, но я не могу понять, где - person HuwF; 19.04.2013
comment
Ok. Прохладный. Моя следующая догадка, и я уверен, что вы уже подумали об этом, заключается в том, что в поле числового типа есть строка. пример: предполагается, что CarId является числовым полем. CarId = моя хорошая машина. - person Erik Volkening; 19.04.2013
comment
Как вы сказали, я уже думал об этом, и, насколько я могу судить, у меня нет строк в моих числовых полях. Чтобы собрать все данные, я использую объект List‹, так как есть строки и целые числа, которые нужно взять, может ли это быть проблемой? Также спасибо, что прошли через это со мной! - person HuwF; 19.04.2013
comment
Одна вещь, которую вы можете попробовать, если хотите использовать параметры, — это код ниже. Я не знаю, решит ли это вашу проблему или нет, но, по крайней мере, это поможет защитить вас от атак SQL Injection. Пожалуйста, дай мне знать, если возникнут какие-либо вопросы. - person Erik Volkening; 19.04.2013
comment
Я не уверен, что понимаю вас, что вы подразумеваете под кодом ниже? База данных будет использоваться только в локальной сети, не подключенной к Интернету, поэтому SQL-инъекция будет сложной для выполнения атаки. - person HuwF; 19.04.2013
comment
Ok. Круто. нп. Всегда пожалуйста. Извините, мой код не помещался в комментариях, поэтому я добавил его в свой ответ выше. - person Erik Volkening; 19.04.2013
comment
Ok. два последних предложения. 1). вы можете сделать .toStrings() для известных строковых полей и int.parse() для известных полей int. Я не знаю, поможет это или нет, и это может быть больно, поэтому, возможно, сначала попробуйте № 2. 2). ограничьте количество добавляемых параметров, пока не найдете проблему, например: for (i = 0; i ‹ 1; i++). Если это не сработает, попробуйте (i = 0; i ‹ 2; i++) и т. д., пока не найдете неверный параметр. тогда у вас может быть лучшее представление о том, какой параметр вызывает проблемы и как это исправить. - person Erik Volkening; 19.04.2013
comment
Кажется, что @ все еще присутствует, а не заменяется кодом .AddWithValue. - person HuwF; 19.04.2013