使用动态列名称更新 TABLE
UPDATE TABLE with dynamic COLUMN name
我在从 HTML 表单获取的数组中有动态数量的数据值。
现在我想用这些数据更新我的 table。
列名是 column1
, column2
...等等;
我在 array[]
中有数据,在 unumber
中有要更新的列数
我正在使用此代码,但它不起作用。
P.S:我是编码新手,所以它可能很幼稚。
for(int i=1; i<=unumber; i++)
{
String username = "someuser";
String column = "column" + Integer.toString(i);
PreparedStatement pr = null;
String query1 = "update table1 set (?) = (?) where username = (?)";
pr = con.prepareStatement(query1);
pr.setString(1, column);
pr.setString(2, array[i]);
pr.setString(3, someuser);
int s = pr.executeUpdate();
}
AFAIK,你不能为此使用 "prepared statements"。您可以通过自己在查询中执行插入来解决它:
String query1 = "update table1 set "+column+" = ? where username = ?";
pr = con.prepareStatement(query1);
pr.setString(1, array[i]);
pr.setString(2, someuser);
但是注意sql注入。您最好检查列的可能值是否不能更改。 验证导致确定列名称的所有输入。
确保用户不能指定列 his/herself:否则可以将列设置为 password
并为某些用户设置密码。然后使用该密码登录。或者可以尝试将 column
设置为 '; drop table foo; select * where x
PreparedStatment
s 只能绑定值,不能绑定语法元素或对象名,比如列,所以这种方法行不通。您将不得不退回到字符串操作:
for(int i=0; i<unumber; i++) {
String username = "someuser";
String column = "column" + Integer.toString(i);;
PreparedStatement pr = null;
String query1 = "update table1 set " + column + " = (?) where username = (?)";
pr = con.prepareStatement(query1);
pr.setString(1, column);
pr.setString(2, someuser);
int s = pr.executeUpdate();
}
此外,由于您正在使用相同的 where 子句更新多个列,因此您可以遍历这些列并仅构造 一个 更新语句。它会迫使你有两个循环(一个用于构建查询,一个用于在查询准备好后绑定值),但它仍然应该快得多,因为你只访问数据库一次而不是 N 次:
String username = "someuser";
StringBuilder sql = new StringBuilder("update table1 set ");
for(int i=0; i < unumber; i++) {
sql.append("column")
.append(i).
.append(" = ?");
if (i != (unumber - 1)) {
sql.append(", ");
}
}
sql.append("where username = (?)");
PreparedStatement pr = con.prepareStatement(sql.toString());
for(int i = 0; i < unumber; i++) {
pr.setString(i, array[i]);
}
pr.setString(unumber, someuser);
int s = pr.executeUpdate();
我在从 HTML 表单获取的数组中有动态数量的数据值。
现在我想用这些数据更新我的 table。
列名是 column1
, column2
...等等;
我在 array[]
中有数据,在 unumber
中有要更新的列数
我正在使用此代码,但它不起作用。
P.S:我是编码新手,所以它可能很幼稚。
for(int i=1; i<=unumber; i++)
{
String username = "someuser";
String column = "column" + Integer.toString(i);
PreparedStatement pr = null;
String query1 = "update table1 set (?) = (?) where username = (?)";
pr = con.prepareStatement(query1);
pr.setString(1, column);
pr.setString(2, array[i]);
pr.setString(3, someuser);
int s = pr.executeUpdate();
}
AFAIK,你不能为此使用 "prepared statements"。您可以通过自己在查询中执行插入来解决它:
String query1 = "update table1 set "+column+" = ? where username = ?";
pr = con.prepareStatement(query1);
pr.setString(1, array[i]);
pr.setString(2, someuser);
但是注意sql注入。您最好检查列的可能值是否不能更改。 验证导致确定列名称的所有输入。
确保用户不能指定列 his/herself:否则可以将列设置为 password
并为某些用户设置密码。然后使用该密码登录。或者可以尝试将 column
设置为 '; drop table foo; select * where x
PreparedStatment
s 只能绑定值,不能绑定语法元素或对象名,比如列,所以这种方法行不通。您将不得不退回到字符串操作:
for(int i=0; i<unumber; i++) {
String username = "someuser";
String column = "column" + Integer.toString(i);;
PreparedStatement pr = null;
String query1 = "update table1 set " + column + " = (?) where username = (?)";
pr = con.prepareStatement(query1);
pr.setString(1, column);
pr.setString(2, someuser);
int s = pr.executeUpdate();
}
此外,由于您正在使用相同的 where 子句更新多个列,因此您可以遍历这些列并仅构造 一个 更新语句。它会迫使你有两个循环(一个用于构建查询,一个用于在查询准备好后绑定值),但它仍然应该快得多,因为你只访问数据库一次而不是 N 次:
String username = "someuser";
StringBuilder sql = new StringBuilder("update table1 set ");
for(int i=0; i < unumber; i++) {
sql.append("column")
.append(i).
.append(" = ?");
if (i != (unumber - 1)) {
sql.append(", ");
}
}
sql.append("where username = (?)");
PreparedStatement pr = con.prepareStatement(sql.toString());
for(int i = 0; i < unumber; i++) {
pr.setString(i, array[i]);
}
pr.setString(unumber, someuser);
int s = pr.executeUpdate();