首页 > 解决方案 > 如何修改更新命令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;
    }

标签: c#postgresqlsql-updatenpgsql

解决方案


上面的代码示例存在一些问题,应该会阻止它工作。我对注释代码行的工作感到有些震惊。

  1. 您没有引用您更新的值
  2. 即使您确实引用了它们,也应该使用参数。
  3. 数据阅读器用于阅读。如果您正在执行 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,但是它们增加了很多复杂性,这看起来应该是一个简单的问题。


推荐阅读