c# - 如何修改更新命令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;
}
解决方案
上面的代码示例存在一些问题,应该会阻止它工作。我对注释代码行的工作感到有些震惊。
- 您没有引用您更新的值
- 即使您确实引用了它们,也应该使用参数。
- 数据阅读器用于阅读。如果您正在执行 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,但是它们增加了很多复杂性,这看起来应该是一个简单的问题。
推荐阅读
- java - 在java 8中合并recusive Hashmap
- javascript - 有什么区别?异步与嵌套承诺语句
- azure-devops - 在 Azure DevOps (ADO) 中根据草稿拉取请求自动触发拉取请求构建
- dhtml - DHTMLX Scheduler Month 仅查看事件计数
- android - 如何更改抽屉菜单中的第一个片段
- python - Scikit-Learn 投票分类器预测器分数始终为 0
- postgresql - 如何为多组 id 获取某些条件下的行
- javascript - 数据表 columndefs 没有被击中
- python - 我们可以从 url.py 将参数嵌入到 Django 应用程序的 URL 中吗?
- python - 尝试在 python jupyter 中打开 url 时出错