2013-05-30 4 views
0

Моего кодом:получить столбец из базы данных, используя строку

SqlCommand command = new SqlCommand("SELECT min(Score) FROM MenAthletics WHERE [(@sportevent)] < (@result);", connect); 
     command.Parameters.AddWithValue("@sportevent", sportEvent); 
     command.Parameters.AddWithValue("@result", result); 

@result отлично (только двойной переменный) @sportevent doesnt't работы (ошибка: недопустимый имя_столбец) работает (является Спортивной строкой)

Как я могу выбрать столбец, указав строку?

+2

Кажется, что ваш фактический вопрос должен быть «Можно ли использовать параметры в именах столбцов?» – Mansfield

+0

Я думаю, что вы сравниваете строку и двойной – Bosak

+0

http://stackoverflow.com/questions/10092869/can-i-pass-column-name-as-input-parameter-in-sql-stored-procedure – Apocalyp5e

ответ

1

Вы можете динамически строить SQL-запрос вместо того, чтобы передавать имя столбца в качестве параметра.

+0

спасибо! не сделал этого, потому что я испугался за SQL-инъекцию, но имя столбца указывается в раскрывающемся списке. – user2323240

+1

Ой, это немного страшно - вы должны идеально сопоставить входящий выпадающий ввод с именем столбца на стороне сервера, прежде чем пытаться использовать его в SQL-запросе. Хотя это комбинированный блок, и вы ожидаете, что пользователь будет ограничен опциями, хакер может использовать плагины типа «Тампер» и работать с ограничениями. – aquaraga

4

Вы можете параметризовать значения в операторах SQL, но вы не можете параметризовать имена столбцов или таблиц. Вам нужно изменить имя столбца в самой SQL строки, например, с string.Format:

SqlCommand command = new SqlCommand(
    string.Format("SELECT min(Score) FROM MenAthletics WHERE [{0}] < (@result);", sportEvent) 
, connect 
); 
command.Parameters.AddWithValue("@result", result); 

Убедитесь, что имя столбца не приходит из ввода пользователя, в противном случае вы бы открыть код для атак путем внедрения SQL , В случае, если имя столбца поступает от ввода пользователя, вы можете проверить строку на список доступных столбцов таблицы, которые могут быть сделаны статически или путем изучения структуры вашей таблицы во время выполнения.

+0

Просто из любопытства, как лучше всего предотвратить инъекцию SQL в этом случае, если имя столбца введено пользователем? – Mansfield

+2

@Mansfield Поскольку список столбцов конечен, вы можете проверить ввод на полный список и вывести ошибку, если указанное пользователем имя не входит в число доступных столбцов. – dasblinkenlight

+1

Кроме того, убедитесь, что учетные данные, которые вы подключаете к базе данных, имеете только достаточное разрешение для выполнения необходимых действий, а не объектов DROP и т. Д. Кроме того, если это выпадающее меню и у вас есть веб-приложение, убедитесь, что вы проверяете, значение, отправленное с клиентом, фактически существует в вашем списке после отправки запроса - простое обращение к HTTP-формам. – dash

0

Это потому, что значение в строке sportEvent, которое вы передаете как параметр, не соответствует фактическому столбцу, существующему в вашей таблице базы данных.

Удостоверьтесь, что оба они соответствуют, и тогда только эта ошибка пойдет.

В противном случае не передайте имя столбца таблицы в качестве параметра, непосредственно напишите его в запросе и пусть его значение столбца будет параметром.

Надеюсь, это поможет.

1

Вы не можете использовать имя столбца в качестве параметра; вы должны рассмотреть вместо построения ваш запрос таким образом:

SqlCommand command = 
     new SqlCommand(
     String.Format(@"SELECT min(Score) 
         FROM MenAthletics WHERE [{0}] < @result;",  
         sportEvent), 
         connect); 
command.Parameters.AddWithValue("@result", result); 

Этот вид SQL называется «динамический SQL» и может быть эффективным способом построения запросов на лету.

Однако, есть pitfalls. Помимо проверки ввода пользователя, также убедитесь, что пользователь, которого вы подключаете к базе данных, имеет только достаточные разрешения для выполнения действий, которые вы хотите выполнить.

Другой подход, который менее изящный, но может быть помещен непосредственно в хранимую процедуру, заключается в использовании оператора CASE;

Например:

SELECT min(Score) 
FROM MenAthletics 
WHERE 
    CASE 
     WHEN @sportEvent = 'SomeColumnName' THEN SomeColumnName 
     WHEN @sportEvent = 'SomeColumnName2' THEN SomeColumnName2 
    END < @result; 

Это становится очень утомительным, как создавать и поддерживать на больших таблицах. Преимущество заключается в том, что запрос не является динамическим.

Смежные вопросы