SelectCommand с параметрами обеспечивает пустой результат
В настоящее время я немного уберу свой код, и VS сказал мне, что лучше использовать SqlParameter
для команд sql вместо составного string
, Поэтому я решил изменить свой код, к сожалению, сейчас у меня нет результата, и я не знаю почему. Вот часть моего кода:
...
DataTable dt = new DataTable();
SqlConnection connection = new SqlConnection(GetSQLConnectionString());
SqlDataAdapter sqlSelect = new SqlDataAdapter();
try
{
connection.Open();
sqlSelect.SelectCommand = connection.CreateCommand();
sqlSelect.SelectCommand.CommandText = "SELECT id, @FROM AS \"from\", @TO AS \"to\" FROM Dictionary WHERE @FROM LIKE @SEARCHSTRING";
sqlSelect.SelectCommand.Parameters.Add(new SqlParameter("@FROM", this.from));
sqlSelect.SelectCommand.Parameters.Add(new SqlParameter("@TO", this.to));
sqlSelect.SelectCommand.Parameters.Add(new SqlParameter("@SEARCHSTRING", "'%" + this.SearchField.Text + "%'"));
sqlSelect.Fill(dt);
connection.Close();
}
catch(SqlException e)
...
Я не получаю никаких исключений. Почему после поиска dt пуст? (С составной строкой, выбор работает.) Что пошло не так?
Greetz
4 ответа
Как уже говорили, проблема в том, что вы не можете передавать имена полей в качестве параметров.
Подход, который вы выбираете, является плохой идеей по нескольким причинам: во-первых, когда вы передаете команду sql таким образом, сервер должен перекомпилировать ее каждый раз, когда вы выполняете этот запрос, это создает дополнительную нагрузку на сервер и снижает производительность. Во-вторых, это риск для безопасности, передавая ваши операторы выбора подобным образом, поскольку это дает любому, кто его перехватывает, взгляд на структуру вашей таблицы. В-третьих, использование операторов выбора, подобных этому, означает, что если вы когда-нибудь захотите повторно использовать код, который вы не можете использовать без копирования.
Я бы порекомендовал перейти на хранимую процедуру. вы все равно можете передать свои параметры и т. д., но это улучшит ваш код, поскольку он убирает SQL из C# и оставляет только то, что имеет отношение к делу.
Если вам ДЕЙСТВИТЕЛЬНО нужно передать имена полей, которые будут использоваться в операторе выбора, подобным этому, вы можете сделать это в SQL и создать строку запроса, а затем выполнить ее с помощью sp_executesql.
По сути, вы объявляете строку запроса как
DECLARE @queryString VARCHAR(3000)
SET @queryString ='SELECT id, '+@FROM+' AS from, '+@TO+' AS to FROM Dictionary WHERE +'@FROM+' LIKE %'+@SEARCHSTRING+'%'
затем просто используйте sp_executesql для выполнения @queryString
Вам может потребоваться привести параметры к Varchar, хотя, если вы получаете какие-либо ошибки при создании строки запроса
Вы не можете указывать имена полей, используя такие параметры. В вашем пункте, где WHERE @FROM LIKE @SEARCHSTRING
это сравнение значения параметра @FROM
со значением параметра @SEARCHSTRING
,
Если предложение where оценивается как true, вы получите каждую запись в таблице словаря, если оно оценивается как false, вы не получите никаких записей. Он никогда не будет обрабатывать содержимое @from как имя поля в таблице словаря.
Почему вы написали такой запрос?
"SELECT id, @FROM AS \"from\", @TO AS \"to\" FROM Dictionary WHERE @FROM LIKE @SEARCHSTRING";
Вы пытаетесь получить @FROM из таблицы и также передать его в качестве параметра, как это должно работать? Кроме того, почему вы включили косые черты? они просто запутывают, удаляют их. Запрос Select принимает входные параметры только с предложением WHERE и больше нигде.
Попробуйте заменить это этим
"SELECT id, FROM AS 'from', TO AS 'to' FROM Dictionary WHERE FROM LIKE @SEARCHSTRING";
Также удалите все, кроме последних случаев:
sqlSelect.SelectCommand.Parameters.Add
Также позаботьтесь о том, чтобы "FROM" также являлось ключевым словом SQL, поэтому убедитесь, что оно правильно интерпретируется, заключив его в "[]".
Надеюсь это поможет...
Этот:
sqlSelect.SelectCommand.Parameters.Add(new SqlParameter("@SEARCHSTRING", "'%" + this.SearchField.Text + "%'"));
должно быть:
sqlSelect.SelectCommand.Parameters.Add(new SqlParameter("@SEARCHSTRING", "%" + this.SearchField.Text + "%"));