我正在编写一个类来处理我的应用程序中的所有数据库活动,所以我来到执行UPDATE查询的方法。
截至目前,我正在返回并显示commandtext的内容以进行检查,看起来很好:
UPDATE news SET title = @title, newsContent = @newsContent, excerpt = @excerpt, date = @date, urlTitle = @urlTitle, isPublished = @isPublished WHERE (id = @id);
所以,换句话说,很好。下一步是用实际值替换所有@values - 这就是我遇到问题的地方。什么都没发生。 AddWithValue方法似乎没有做任何事情,我没有理由这样做。
public string updateQuery(string table, string[] fields, object[] values, string conditionField, object conditionValue)
{
try
{
StringBuilder cmd = new StringBuilder("UPDATE " + table + " SET ");
int i = 1;
foreach (string s in fields)
{
if (i == fields.Length)
{
cmd.Append(s + " = @" + s + " ");
}
else
{
cmd.Append(s + " = @" + s + ", ");
}
i++;
}
cmd.Append("WHERE (" + conditionField + " = @" + conditionField + ");");
command.CommandText = cmd.ToString();
int j = 0;
foreach (object o in values)
{
command.Parameters.AddWithValue("@" + fields[j], o);
j++;
}
command.Parameters.AddWithValue("@" + conditionField, conditionValue);
command.ExecuteNonQuery();
connection.Close();
return command.CommandText;
}
catch (Exception ex)
{
throw ex;
}
}
任何?
答案 0 :(得分:2)
“你什么都不做”是什么意思?你是说在执行命令时参数没有值?或者命令文本保持不变?
如果是后者那么这是预期的。该命令不会更改查询文本,它会将查询文本与参数值一起发送到服务器。
答案 1 :(得分:2)
感谢Joel Coehoorn的建议,我会调查他们。
不过,我想让我的东西上班:p
注意到日期字段实际上一直在更新自己。但是,没有其他领域。这看起来越不正确。也许在早上尝试比在午夜更好。
编辑: 找出问题所在,这比我预期的要简单得多。我忘了检查页面是否是回发,因此每次更新数据库时,在调用submit-method之前,字段都填充了数据库中的数据。因此,更新方法始终如一。 腮红
答案 2 :(得分:1)
arg值是否可能为空?如果是这样,则不会添加参数。对于null,您需要使用DBNull.Value
;例如(不是唯一的方法):
cmd.Parameters.AddWithValue(argName, (object)argValue ?? DBNull.Value);
答案 3 :(得分:1)
您提供的ID的值可能与您要更新的表中的条目不匹配。
BTW放弃了try ..catch它没有任何用途。
答案 4 :(得分:1)
如果您希望更新字符串,您会感到失望。使用参数化查询的一个重要特性是,值永远不会直接替换为命令字符串,因此您可以免受此类安全漏洞的影响。相反,数据会单独传输到服务器。
让我建议这个新功能签名:
public string updateQuery(string table, IEnumerable<KeyValuePair<string, object>> values, KeyValuePair<string, object> condition)
这将在您的参数名称和值之间建立强关联,并且还可以灵活地使用除数组之外的构造(尽管也可以接受数组)。然后代码看起来像这样:
public string updateQuery(string table, IEnumerable<KeyValuePair<string, object>> values, KeyValuePair<string, object> condition)
{
using (StringBuilder cmd = new StringBuilder("UPDATE [" + table + "]\nSET "))
{
string delimiter = "";
foreach (KeyValuePair<string, object> item in values)
{
cmd.AppendFormat("{0}[{1}]=@{1}", delimiter, item.Key);
delimiter = ",\n";
}
cmd.AppendFormat("\nWHERE [{0}]= @{0};", condition.Key);
command.CommandText = cmd.ToString();
}
foreach (KeyValuePair<string, object> item in values)
{
command.Parameters.AddWithValue("@" + item.Key, (object)item.Value ?? DBNull.Value);
}
command.Parameters.AddWithValue("@" + condition.Key, condition.Value);
// you didn't show where the connection was created or opened
command.ExecuteNonQuery();
connection.Close();
return command.CommandText;
}
如果您可以使用能够创建强类型数据库参数的东西(例如IEnumerable<SqlParameter>
),那就更好了。
答案 5 :(得分:0)
我猜我还会发布其余的代码。首先传递值的方法:
public void updatePost(int postId)
{
DbConnection d = new DbConnection();
string[] fields = {
"title",
"newsContent",
"excerpt",
"date",
"urlTitle",
"isPublished"
};
object[] values = {
this.title,
this.content,
this.excerpt,
this.date,
this.urlTitle,
this.isPublished,
};
d.updateQuery("news",fields,values,"id",postId);
}
连接到数据库的构造方法:
public DbConnection()
{
connection = new SqlConnection("Data Source=****; User Id=****; Password=*****;");
connection.Open();
command = connection.CreateCommand();
}
我还没有找到问题所在,但我真的非常感谢所有帮助。 : - )
答案 6 :(得分:0)
使用我的其他代码,您的新updatePost方法将如下所示。
using DBParam = KeyValuePair<string, object>; // reduce need to keep re-typing this
public void updatePost(int postId)
{
List<DBParam> values = new List<DBParam>();
values.Add(new DBParam("title", this.title));
values.Add(new DBParam("newsContent", this.content));
values.Add(new DBParam("excerpt", this.excerpt));
values.Add(new DBParam("date", this.date));
values.Add(new DBParam("urlTitle", this.urlTitle));
values.Add(new DBParam("isPublished", this.isPublished));
new DbConnection().updateQuery("news", values, new DBParam("id", postid));
}