Как изменить установленное значение команды обновления npgsql postgresql C#
Я пытался изменить команду sql для postgresql на C#. Строка в кавычках комментария работает, но мне нужно изменить набор с предопределенного на переменный. Хотя после использования того же способа определения его как переменной с текстом, заданным пользователем в другой форме, похоже, он не работает. Какой правильный способ заменить "first_name" на переменную?
String oldname = Actor.oldname;
String newname = Actor.newname;
String column = Actor.columnname;
try
{
string connstring = "Server=127.0.0.1; Port=5432; User Id=postgres; Password=72677267; Database=imdb;";
NpgsqlConnection connection = new NpgsqlConnection(connstring);
connection.Open();
//NpgsqlCommand command = new NpgsqlCommand("UPDATE actor SET first_name = " + newname + " WHERE first_name =" + oldname + "", connection);
NpgsqlCommand command = new NpgsqlCommand("UPDATE actor SET " + column + " = " + newname + " WHERE " + column + " =" + oldname + "", connection);
NpgsqlDataReader dataReader = command.ExecuteReader();
connection.Close();
return dataItems;
}
catch (Exception msg)
{
MessageBox.Show(msg.ToString());
throw;
}
1 ответ
У вас есть несколько проблем с приведенным выше примером кода, которые должны помешать его работе. Я немного шокирован тем, что закомментированная строка кода работает.
- Вы не цитируете значения, которые вы обновляете
- Даже если вы указали их в кавычках, вы должны вместо этого использовать параметры.
- Читатель данных предназначен для чтения. Если вы выполняете DML, вы должны использовать
ExecuteNonQuery
, Если у вас есть возвращаемые значения, это может быть причиной для чтения данных, но в этом случае вам это не нужно.
Все это говорит о том, что динамический SQL иногда неизбежен, но я бы порекомендовал все возможные варианты, прежде чем отказаться от создания динамического SQL. Если вам нужно, один из способов смягчить это может заключаться в том, чтобы иметь конечное число опций, поэтому вместо того, чтобы позволить им обновлять ЛЮБОЕ поле, позвольте им выбрать поле из списка опций.
Это все еще динамический SQL, но он, по крайней мере, параметризован, а возможности внедрения по крайней мере ограничены методом, что делает любую инъекцию очень маловероятной.
public enum ActorField
{
FirstName,
LastName,
Salutation
}
public void UpdateActorField(string OldName, string NewName, ActorField FieldId)
{
string sql = "update actor set {0} = :NEW_NAME where {0} = :OLD_NAME";
switch (FieldId)
{
case ActorField.FirstName
sql = string.Format(sql, "first_name");
break;
case ActorField.LastName
sql = string.Format(sql, "last_name");
break;
case ActorField.Salutation
sql = string.Format(sql, "salutation");
break;
}
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, connection))
{
cmd.Parameters.AddWithValue("NEW_NAME", NewName);
cmd.Parameters.AddWithValue("OLD_NAME", OldName);
int updatedRows = cmd.ExecuteNonQuery();
}
}
Существуют более удачные способы сделать это с помощью одного оператора SQL и без динамического SQL, но они значительно усложняют то, что кажется простой задачей.