我目前正在开展一个项目,该项目要求我构建一个类,用于将文件中的数据详细信息上传到数据库中的预准备表中。到目前为止,我做得很好,但我的挑战是将数据格式化为插入到java中可接受的sqlite语句格式。这是我的代码......
import java.io.*;
import java.sql.*;
import javax.swing.JOptionPane;
public class Data_Update {
Connection conn = JavaConnect.Connecrdb();
PreparedStatement pst = null;
File c;
Data_Update(File d) {
this.c = d;
}
boolean testFile() {
System.out.println(c.getName().substring(c.getName().length() - 4, c.getName().length()));
boolean t = c.getName().substring(c.getName().length() - 4, c.getName().length()).equals(".sql");
return t;
}
boolean createTable() throws FileNotFoundException, IOException, SQLException {
String r = "", p, q = "";
try {
FileInputStream h = new FileInputStream(c);
DataInputStream k = new DataInputStream(h);
BufferedReader j = new BufferedReader(new InputStreamReader(k));
while ((p = j.readLine()) != null) {
String s = "";
if ((p.startsWith("("))) {
while (!s.contains(")")) {
s = s + p;
}
if (s.contains(", \'")) {
System.out.println("Yes");
} else {
System.out.println("No");
}
s.replaceAll("\'str\'", "\'\"+str+\"\'");
s.replace(", \'", ", \'\"+");
s.replace("\',", "+\"\',");
s.replace("(\'", "(\'\"+");
s.replace("\')", "+\"\')");
s.replace("),", ")");
System.out.println(s);
pst = conn.prepareStatement("insert into courseinformation (currentsession, regno, fullname, level, previouscourses, gpa,
outstandingcourses, proposedcourses, totalcourseno, totalunit, registered, pre_userid, dept, sch, registrationpin, refdatetime)
values " + s);
pst.execute();
}
}
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
return false;
}
return true;
}
}
结果是所有替换后的最终字符串不能满足插入记录的sql语句标准
答案 0 :(得分:0)
使用给定的代码很难创建一个立即起作用的代码,但您可以从此开始作为基础。
似乎你用引号,逗号和括号读取SQL,并尝试使用加号和双引号制作一些包含准java的字符串。这被认为太过分了:简单的SQL工作。
虽然在这里我没有构建SQL文本片段,但是将输入行拆分为要设置的单个值。 这可以扩展到字段验证和字符串到特定类型的转换。
第一步是在 单一交易中执行所有执行。这是一个很大的加速。这意味着最后有一个提交,因此每个语句的自动提交必须设置为false。并且在例外情况下回滚。
提前定义PreparedStatement。
使用try-with-resources(try (X x = ...) { }
)会自动关闭资源(x
)。
这里我对数据做了一些假设。就像逗号不在输入中作为文本值的一部分。
没有给出编码的InputStreamReader将采用本地平台编码,这是非可移植的:可能使用错误的编码读取另一台PC上的相同文件。
既没有字段验证也没有转换,始终使用setString
。
public void createTable(Connection conn, File c) throws IOException, SQLException {
final int fieldCount = 16;
conn.setAutoCommit(false);
try (PreparedStatement pst = conn.prepareStatement(
"insert into courseinformation (currentsession, regno, fullname, level, "
+ "previouscourses, gpa, outstandingcourses, proposedcourses, "
+ "totalcourseno, totalunit, registered, pre_userid, dept, sch, "
+ "registrationpin, refdatetime) "
+ "values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)")) { // 16 columns
try (BufferedReader in = new BufferedReader(
new InputStreamReader(new FileInputStream(c), "UTF-8"))) {
String line;
while ((line = in.readLine()) != null) {
// Assume that line is " ('...', ..., '...'),"
line = line.replaceFirst("^\\s*\\((.*)\\),?\\s*", "$1").trim();
String[] fields = line.split(",\\s*", fieldCount);
for (int i = 0; i < fieldCount; ++i) {
String field = fields[i].trim().replaceFirst("^'(.*)'$", "$1");
pst.setString(1 + i, field); // SQL column nos counted from 1.
}
pst.execute();
}
}
conn.commit();
} catch (Throwable e) {
conn.rollback();
throw e;
}
}
答案 1 :(得分:0)
String.replace
和String.replaceAll
不会更改您的String
对象,它们会在替换后返回新的字符串,因此您应该编写s = s.replace...
您的代码中还有很多其他问题,例如
while (!s.contains(")")) {
s = s + p;
}
如果p
不包含)
,则是无限循环
另外,手动转义字符串是在java中使用sql api的错误方法,你应该在你的语句中使用占位符和绑定参数。