如何格式化String以符合PreparedStatement可插入的插入格式

时间:2014-09-30 15:22:02

标签: java sql

我目前正在开展一个项目,该项目要求我构建一个类,用于将文件中的数据详细信息上传到数据库中的预准备表中。到目前为止,我做得很好,但我的挑战是将数据格式化为插入到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语句标准

2 个答案:

答案 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.replaceString.replaceAll不会更改您的String对象,它们会在替换后返回新的字符串,因此您应该编写s = s.replace...

您的代码中还有很多其他问题,例如

                while (!s.contains(")")) {

                    s = s + p;

                }
如果p不包含)

,则

是无限循环

另外,手动转义字符串是在java中使用sql api的错误方法,你应该在你的语句中使用占位符和绑定参数。