如何同时插入和选择mysql

时间:2013-11-16 07:14:21

标签: java mysql sql jdbc

我有一个要求,我需要在mysql中插入手机号码,当且仅当号码不存在时。为此,我首先检查mysql中是否存在使用select查询的号码。如果号码不存在然后插入。以下是我的代码

PreparedStatement pt1=con.prepareStatement("select * from registerSmsUsers where mobile='"+mobile+"'");
PreparedStatement pt=con.prepareStatement("insert into registerSmsUsers values(?,?,?)");
        pt.setString(1, name);
        pt.setString(2, email);
        pt.setString(3, mobile);
ResultSet rs1=pt1.executeQuery();
        if(rs1.next())

{pt.executeUpdate();}

我不知道这是否是一种有效的方法。请给我一个更好的方法然后这个

5 个答案:

答案 0 :(得分:2)

可能是mysql中最简单的方法是:

insert ignore into registerSmsUsers values(?,?,?)

假设您在移动设备上有唯一的密钥

您可以在此处查看:How to 'insert if not exists' in MySQL?

或者在这里:http://dev.mysql.com/doc/refman/5.6/en/insert.html

答案 1 :(得分:2)

许多提议的解决方案(包括您的解决方案)都存在可能导致主键或唯一约束违规的竞争条件。您的代码也可能通过连接SQL而不是使用预准备语句参数来进行SQL注入攻击。使用SELECT ... FOR UPDATE。

PreparedStatement ps = con.prepareStatement("SELECT name, email, mobile FROM registerSmsUsers WHERE mobile=? FOR UPDATE",
                                            ResultSet.TYPE_FORWARD_ONLY,
                                            ResultSet.CONCUR_UPDATABLE);
ps.setString(1, mobile);
ResultSet rs = ps.executeQuery();
if (rs.next()) { // it exists already
   rs.moveToCurrentRow();
   rs.updateString(3, mobile);
   rs.updateRow();
} else { // it does NOT exist
   rs.moveToInsertRow();
   rs.updateString(1, name);
   rs.updateString(2, email);
   rs.updateString(3, mobile);
   rs.insertRow();
}
rs.close();
ps.close();

编辑:请确保您在registerSmsUsers上有索引。

CREATE INDEX registerSmsUsers_mobile_ndx ON registerSmsUsers(mobile)

或唯一的约束(隐式创建索引):

ALTER TABLE registerSmsUsers ADD CONSTRAINT registerSmsUsers_mobile_unq UNIQUE (mobile)

使用索引,即使有数百万条记录,更新/插入也基本上是即时的。

EDIT2:添加了光标/结果集选项。

答案 2 :(得分:1)

我认为创建存储过程会更好,然后在该存储过程中,您可以首先使用IF NOT EXISTS子句使用select语句检查用户是否存在。如果用户不在,您可以insert数据库中的用户。

这样的事情:

IF NOT EXISTS(SELECT 1 FROM `registerSmsUsers` WHERE mobile= @mobile) THEN
    BEGIN
    INSERT INTO 
        `registerSmsUsers`
        (
            //column names
        ) 
        VALUES 
        (
            //values
        );
    END;
END IF;

还有一个INSERT IGNORE语句可以像这样使用:

insert ignore into registerSmsUsers values(?,?,?)

答案 3 :(得分:1)

if not exists(select * from registerSmsUsers where mobile='232323') <-- will check your mobile no
begin
 insert into registerSmsUsers values(?,?,?)
end

这个也是一种有效的方法来检查你的方法也工作正常,但这也可以做到 看到区别是你在这里只有一个查询 我希望这会对你有所帮助

[编辑]

您的问题回答

是否在您和我的查询之间存在执行 time diff ,这取决于数据库大小如果您使用的是小型数据库(可能是1000人)然后你不会在你的查询和我的查询之间看到任何差异,但是如果你正在使用十万用户那么你将有一个性能问题检查包括在mysql中执行计划你会得到两个实时差异< / p>

答案 4 :(得分:1)

根据要求,这是我调整的brettw的答案:

import java.sql.*;

public class MySQLtest {

    public static void main(String[] args) {
        Connection con;
        try {
            con = DriverManager.getConnection(
                    "jdbc:mysql://192.168.1.3/zzzTest?" +
                    "useUnicode=yes&characterEncoding=UTF-8" +
                    "&user=root&password=whatever");
            String newName = "Gord";
            String newEmail = "gord@example.com";
            String newMobile = "416-555-1212";
            String sql = 
                    "SELECT " +
                        "id, " +
                        "name, " +
                        "email, " +
                        "mobile " +
                    "FROM registerSmsUsers " +
                    "WHERE mobile = ? " +
                    "FOR UPDATE";
            PreparedStatement pst = con.prepareStatement(
                    sql, 
                    ResultSet.TYPE_FORWARD_ONLY, 
                    ResultSet.CONCUR_UPDATABLE);
            pst.setString(1, newMobile);
            ResultSet rs = pst.executeQuery();
            if (rs.next()) {
                rs.moveToCurrentRow();
                rs.updateString("name", newName);
                rs.updateString("email", newEmail);
                rs.updateRow();
                System.out.println("Existing row updated.");
            }
            else {
                rs.moveToInsertRow();
                rs.updateString("name", newName);
                rs.updateString("email", newEmail);
                rs.updateString("mobile", newMobile);
                rs.insertRow();
                System.out.println("New row inserted.");
            }
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
    }

}

请注意,id是表格的主键:int(11) NOT NULL AUTO_INCREMENT