如何使用 PrepareStatement 在 Java 中执行 INSERT SELECT INTO

Posted

技术标签:

【中文标题】如何使用 PrepareStatement 在 Java 中执行 INSERT SELECT INTO【英文标题】:How to do INSERT SELECT INTO in Java using PrepareStatement 【发布时间】:2015-12-23 18:11:12 【问题描述】:

我正在尝试通过从 2 个表中选择列中的特定数据来执行插入到 1 个表中的 INSERT INTO SELECT。问题是,它也将涉及来自 JTextField 的用户输入。我已经搜索了许多解决方案,但仍然出现错误,我只是不知道还能做什么。我使用 Java 作为 PL 和 Oracle 作为 DB。这是我到目前为止所得到的:

Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","ghost","slayer");

stmt = con.createStatement();

String sbjC = sbjCode.getText(); //textfield for subjectCode
String sbjN = sbjName.getText(); //textfield for subjectName
String matricsno = textstudentid.getText(); //textfield for matrics number
String sbjG = sbjGrade.getText(); //textfield for subjectGrade (not gonna be use in db, just for comparison)

String sql1 = "INSERT INTO transferred (subjectCode,subjectName,credit,prequisite,matricsNo) "
    + "SELECT b.subjectCode,b.subjectName,b.credit,b.prequisite,s.matricsNo "
    + "FROM bitm b, student s "
    + "WHERE b.subjectCode = '"+sbjC+"' AND b.subjectName = '"+sbjN+"' AND s.matricsNo = '"+matricsno+"'";

/* table Transferred has 5 column which are subjectCode,subjectName,credit,prequisite,matricsNo [matricsno as FK]
 * table bitm has 5 column [subjectCode as PK]
 * table student has 6 column [matricsno as PK]
 */

ps = con.prepareStatement(sql1);

ps.setString(1, sbjC);
ps.setString(2, sbjN);
ps.setString(3, "SELECT credit FROM bitm WHERE subjectCode = '"+sbjC+"' AND subjectName = '"+sbjN+"'");
ps.setString(4, "SELECT prequisite FROM bitm WHERE subjectCode = '"+sbjC+"' AND subjectName = '"+sbjN+"'");
ps.setString(5, "SELECT matricsno FROM student WHERE matricsno = '"+matricsno+"'");

ps.executeUpdate(sql1);

执行并将所需的所有数据插入 JTextField 后,我遇到的唯一错误是 java.sql.SQLException : Invalid column index

SQL 语句已在 SQL Developer 中测试并成功。只是我对如何在 Java 上做到这一点有点困惑。 感谢您的所有回复和时间。 我是 Java 新手。

【问题讨论】:

哪一行会产生该错误? .setString 之一?您使用这些行动态设置的相应? 在哪里?见docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html 您的参数完全关闭。您正在尝试将select 查询设置为参数?我认为你需要退后一步,学习准备好的语句如何工作的基础知识。 您的查询没有参数。您需要将? 放入SQL 字符串而不是实际参数中。您也可以使用select 语句作为参数字符串。 ps.setString(1, sbjC); ps.setString(2, sbjN); ps.setString(3, "SELECT credit FROM bitm WHERE subjectCode = '"+sbjC+"' AND subjectName = '"+sbjN+"'"); ps.setString(4, "SELECT prequisite FROM bitm WHERE subjectCode = '"+sbjC+"' AND subjectName = '"+sbjN+"'"); ps.setString(5, "SELECT matricsno FROM student WHERE matricsno = '"+matricsno+"'"); 很奇怪 我试过用 ?我得到的错误是 java.sql.SQLException: ORA-01008: not all variables bound 【参考方案1】:

对于 PreparedStatement,您会编写代码吗?进入 sql 并稍后将其替换为值。

String sql1 = "INSERT INTO transferred (subjectCode,subjectName,credit,prequisite,matricsNo) "
                    + "SELECT b.subjectCode,b.subjectName,b.credit,b.prequisite,s.matricsNo "
                    + "FROM bitm b, student s "
                    + "WHERE b.subjectCode = ?  AND b.subjectName = ? AND s.matricsNo = ? ";


            ps = con.prepareStatement(sql1);

            ps.setString(1, sbjC);
            ps.setString(2, sbjN);
            ps.setString(3,matricsno);

ps.executeUpdate ();

应该这样做。

您的错误来自于提供参数(setString...)而不匹配?

【讨论】:

感谢您的回复。我已经替换它并生成错误:java.sql.SQLException: ORA-01008: not all variables bound 你能用当前代码更新问题吗?三个问号和参数索引 1 到 3 应该可以工作。 感谢您的回复。我已经更新了代码以及我遇到的错误。 检查最后一行!!不是executeUpdate(sql1),只是executeUpdate(); 感谢您的回答。有用!非常感谢。数据已成功插入数据库。 :D【参考方案2】:

很遗憾,您完全误解了preparedStatemet 的作用。 你要写吗? -s 进入查询,preparedStatement 将以键入的方式替换它:

 String sql1 = "INSERT INTO transferred (subjectCode,subjectName,credit,prequisite,matricsNo) "
                    + "SELECT b.subjectCode,b.subjectName,b.credit,b.prequisite,s.matricsNo "
                    + "FROM bitm b, student s "
                    + "WHERE b.subjectCode = ? AND b.subjectName = ? AND s.matricsNo = ?";

            ps = con.prepareStatement(sql1);
            ps.setString(1, sbjC);
            ps.setString(2, sbjN);
            ps.setString(3, matNo);
            ps.executeUpdate();

【讨论】:

尝试添加整个查询作为替换是错误的方法:ps.setString(5, "SELECT matricsno FROM student WHERE matricsno = '"+matricsno+"'");【参考方案3】:

为了回答我自己的问题,我将对我对代码所做的更改发表评论并使其生效:

Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","aza","jaiza");

stmt = con.createStatement();

String sbjC = sbjCode.getText();
String sbjN = sbjName.getText();
String matricsno = textstudentid.getText();
String sbjG = sbjGrade.getText();

String sql1 = "INSERT INTO transferred (subjectCode,subjectName,credit,prequisite,matricsNo) "
        + "SELECT b.subjectCode,b.subjectName,b.credit,b.prequisite,s.matricsNo "
        + "FROM bitm b, student s "
        + "WHERE b.subjectCode = ? AND b.subjectName = ? AND s.matricsNo = ?"; // from textfield to ?

ps = con.prepareStatement(sql1);

ps.setString(1, sbjC);
ps.setString(2, sbjN);
ps.setString(3, matricsno);

//from all the SELECT statement to just 3 user-input-from-textfield column

ps.executeUpdate(); // remove the sql1 in ps.executeUpdate(sql1);

【讨论】:

以上是关于如何使用 PrepareStatement 在 Java 中执行 INSERT SELECT INTO的主要内容,如果未能解决你的问题,请参考以下文章

如何在以下几种方法中关闭 resultSet、prepareStatement、conn 以避免 rs 关闭和连接池被卡住

JDBC PrepareStatement对象执行批量处理实例

在 prepareStatement 中使用 COALESCE 来“插入”cmd

JDBC中使用的java中**Connection接口**的**prepareStatement**的实现在哪里?

prepareStatement与Statement的区别

在 PrepareStatement 中设置参数是不是有任何基于通用的替代方法