如何修改更新命令的设置值npgsql postgresql c#

我一直在尝试在c#上修改postgresql的sql命令。 注释引号中的行是有效的,但我需要将集合从预定义更改为变量。 虽然使用相同的方式将其定义为变量,并且用户在另一个表单上给出了文本,但它似乎不起作用。 用变量替换“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. 您没有引用更新的值
  2. 即使你引用了它们,也应该使用参数。
  3. 数据读取器用于读取。 如果您正在执行DML,则应使用ExecuteNonQuery 。 如果您有返回值,则可能是datareader的原因,但在这种情况下您似乎不需要它。

总而言之,动态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,但是它们会增加很多复杂性,看起来应该是一个简单的问题。