Как выполнить составные SQL-запросы в Java? - PullRequest
2 голосов
/ 21 июля 2011

Как я могу выполнить следующий запрос и получить результат с помощью подготовленного оператора:

INSERT INTO vcVisitors (sid) VALUES (?); SELECT LAST_INSERT_ID();

Есть ли способ выполнить оба этих оператора одновременно?

Я пытался сделать следующее:

Connection con = DbManager.getConnection();
PreparedStatement ps = con.PrepareStatement(
     "INSERT INTO vcVisitors (sid) VALUES (?); SELECT LAST_INSERT_ID();");
ps.setInt(1, 10);
ResultSet rs = ps.exequteQuery();
rs.next();
return rs.getInt("LAST_INSERT_ID()");

, но выдает ошибку, что executeQuery не может выполнить такой запрос, я такжепопытался заменить executeQuery следующим:

ps.execute();
rs = ps.getResultSet();

, но он дает мне синтаксическую ошибку SQL:

You have an error in your SQL syntax; 
check the manual that corresponds to your MySQL server version 
for the right syntax to use near 'SELECT LAST_INSERT_ID()' at line 1

, но нет проблем с выполнением запроса "INSERT INTO vcVisitors (sid) VALUES ('10'); SELECT LAST_INSERT_ID (); " непосредственно из консоли mysql.

Ответы [ 3 ]

2 голосов
/ 21 июля 2011

Как уже говорили другие, это не сработает.Но, похоже, вы просто хотите получить идентификатор последней вставки.Для этого вы можете использовать метод getGeneratedKeys() класса Statement.

2 голосов
/ 21 июля 2011

При обновлении (вставке) данных используйте executeUpdate вместо executeQuery.Попробуйте выполнить SELECT LAST_INSERT_ID() как другой запрос.

Но это не переносимый запрос.Я предлагаю использовать Statement.getGeneratedKeys вместо этого.Пожалуйста, посмотрите здесь: JDBC (MySQL) Получение значений столбца AUTO_INCREMENT .

Вот пример правильно используемого LAST_INSERT_ID ():

    Statement stmt = null;
   ResultSet rs = null;

   try {

    //
    // Create a Statement instance that we can use for
    // 'normal' result sets.

    stmt = conn.createStatement();

    //
    // Issue the DDL queries for the table for this example
    //

    stmt.executeUpdate("DROP TABLE IF EXISTS autoIncTutorial");
    stmt.executeUpdate(
            "CREATE TABLE autoIncTutorial ("
            + "priKey INT NOT NULL AUTO_INCREMENT, "
            + "dataField VARCHAR(64), PRIMARY KEY (priKey))");

    //
    // Insert one row that will generate an AUTO INCREMENT
    // key in the 'priKey' field
    //

    stmt.executeUpdate(
            "INSERT INTO autoIncTutorial (dataField) "
            + "values ('Can I Get the Auto Increment Field?')");

    //
    // Use the MySQL LAST_INSERT_ID()
    // function to do the same thing as getGeneratedKeys()
    //

    int autoIncKeyFromFunc = -1;
    rs = stmt.executeQuery("SELECT LAST_INSERT_ID()");

    if (rs.next()) {
        autoIncKeyFromFunc = rs.getInt(1);
    } else {
        // throw an exception from here
    }

    rs.close();

    System.out.println("Key returned from " +
                       "'SELECT LAST_INSERT_ID()': " +
                       autoIncKeyFromFunc);

} finally {

    if (rs != null) {
        try {
            rs.close();
        } catch (SQLException ex) {
            // ignore
        }
    }

    if (stmt != null) {
        try {
            stmt.close();
        } catch (SQLException ex) {
            // ignore
        }
    }
}

и здесь то же самое сgetGeneratedKeys:

     Statement stmt = null;
   ResultSet rs = null;

   try {

    //
    // Create a Statement instance that we can use for
    // 'normal' result sets assuming you have a
    // Connection 'conn' to a MySQL database already
    // available

    stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
                                java.sql.ResultSet.CONCUR_UPDATABLE);

    //
    // Issue the DDL queries for the table for this example
    //

    stmt.executeUpdate("DROP TABLE IF EXISTS autoIncTutorial");
    stmt.executeUpdate(
            "CREATE TABLE autoIncTutorial ("
            + "priKey INT NOT NULL AUTO_INCREMENT, "
            + "dataField VARCHAR(64), PRIMARY KEY (priKey))");

    //
    // Insert one row that will generate an AUTO INCREMENT
    // key in the 'priKey' field
    //

    stmt.executeUpdate(
            "INSERT INTO autoIncTutorial (dataField) "
            + "values ('Can I Get the Auto Increment Field?')",
            Statement.RETURN_GENERATED_KEYS);

    //
    // Example of using Statement.getGeneratedKeys()
    // to retrieve the value of an auto-increment
    // value
    //

    int autoIncKeyFromApi = -1;

    rs = stmt.getGeneratedKeys();

    if (rs.next()) {
        autoIncKeyFromApi = rs.getInt(1);
    } else {

        // throw an exception from here
    }

    rs.close();

    rs = null;

    System.out.println("Key returned from getGeneratedKeys():"
        + autoIncKeyFromApi);
} finally {

    if (rs != null) {
        try {
            rs.close();
        } catch (SQLException ex) {
            // ignore
        }
    }

    if (stmt != null) {
        try {
            stmt.close();
        } catch (SQLException ex) {
            // ignore
        }
    }
}
1 голос
/ 21 июля 2011

Попробуйте с:

Connection con = DbManager.getConnection();
int lastid = 0;

PreparedStatement psInsert = con.PrepareStatement(
     "INSERT INTO vcVisitors (sid) VALUES (?)");
psInsert.setInt(1, 10);
psInsert.executeUpdate();

PreparedStatement psSelect = 
    con.PrepareStatement("SELECT LAST_INSERT_ID() AS lastid");
ResultSet rs = psSelect.executeQuery();
rs.next();

lastid = rs.getInt("lastid");

rs.close();
psInsert.close();
psSelect.close();
con.close();
return lastid;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...