我目前正在开发一个程序,其功能是存储我的密码,这就是我使用名为Users的SQL数据库的原因。此数据库包含将使用该程序的所有用户的表。这些表有四列:
SiteName, Username, Password, AdditionalInfo
我在更新特定行时遇到问题。这是我得到错误的代码:
public static void editPassword(String user, String siteEdited, String site, String usernamej, String password, String info){
try{
System.out.println(usernamej);
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:res/Users");
c.setAutoCommit(false);
stmt = c.createStatement();
String update = "UPDATE " + user + " set Username = " + usernamej + " where SiteName = " + siteEdited;
stmt.executeUpdate(update);
stmt.close();
c.close();
}catch(Exception e){
System.err.print( e.getClass().getName() + ": " + e.getMessage());
}
}
它是专门用于处理sql数据库的类,当我尝试将用户名更改为' test'时出现以下错误:
java.sql.SQLException:[SQLITE_ERROR] SQL错误或缺少数据库(没有这样的列:test)
答案 0 :(得分:1)
假设您为user
传递的值是表格的名称,那么您的update
字符串将会是
UPDATE usertable SET Username = test where SiteName = siteEditedValue
您需要引用字符串值:
UPDATE usertable SET Username = 'test' where SiteName = 'siteEditedValue'
快速而肮脏的方式是:
String update = "UPDATE " + user + " set Username = '" + usernamej + "' where SiteName = '" + siteEdited + "'";
但是,在这种情况下使用PreparedStatement
会更好(更多,更好):
public static void editPassword(String user, String siteEdited, String site, String usernamej, String password, String info){
try{
System.out.println(usernamej);
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:res/Users");
stmt = c.prepareStatement("UPDATE " + user + " SET Username = ? Where SiteName = ?");
stmt.setString(1, usernamej);
stmt.setString(2, siteEdited);
stmt.executeUpdate();
stmt.close();
c.close();
}catch(Exception e){
System.err.print( e.getClass().getName() + ": " + e.getMessage());
}
}
此代码假定stmt
的类型为PreparedStatement
,而不仅仅是Statement
。
除了为你引用值之外,这将为你逃避任何sql,防止SQL注入攻击的可能性(虽然这些在桌面应用程序中远不是web应用程序的问题,它是仍然是一个良好的习惯进入)。
答案 1 :(得分:0)
@griFlo我用这段代码运行了它:
Organic Paid EmailCampaign Total ProjectName Month Year
4444 5555 2222 1111 demo project Feb 2015
1252 121 121 1494 debug test Aug 2015
我忘了把c.commit();