多次插入 SQL 数据库

Posted

技术标签:

【中文标题】多次插入 SQL 数据库【英文标题】:Inserting into SQL Database more than once 【发布时间】:2016-10-04 03:01:42 【问题描述】:

我正在制作一个代码生成器,它会生成一个新代码,然后查询数据库以查看它是否存在。如果是这样,请再次尝试制作不同的代码。如果不存在,则将其添加到数据库中。但是当我将一个代码添加到数据库中时,查询会添加 3 个具有 3 个不同值的不同行。其中一个值是应该添加的值,另外两个我不知道它们来自哪里。为什么我只设置为添加一个时它会插入 3。我的完整课程文件是:

package com.xium.accesscode;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.concurrent.ThreadLocalRandom;

import com.xium.log.ServerLogger;
import com.xium.sql.DBConnections;
import com.xium.utils.StringUtils;

public class NewAccessCode 

static String AccessCodeDBuser = "root";
static String AccessCodeDBpass = "";
static String AccessCodeDBhost = "localhost";

static String newAccessCode;
static String randS;
static String randFinal;

static int min = 000000000;
static int max = 999999999;
static int randI;

public static void AccessCode() 
    if(newAccessCode() == 0) 
        ServerLogger.writeLog("[ALERT] Database Error");
     else if(newAccessCode() == 1) 
        //Reruns the code generator, to make a unique code
        newAccessCode();
     else if(newAccessCode() == 2) 
        ServerLogger.writeLog("[NOTE] New Access Code: " + newAccessCode);
    


/*
 * Return Codes:
 * 0 - Database Error
 * 1 - Code Already Exists
 * 2 - New Access Code Added
 */

private static int newAccessCode() 
    genAccessCode();
    newAccessCode = randFinal;

    //Does it already exist?
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    ResultSet results = null;
    String statement = "SELECT count(*) FROM `xium`.`accesscodes` WHERE `accesscode`='" + newAccessCode + "'";
    String statement2 = "INSERT INTO `xium`.`accesscodes` (`accesscode`, `used`, `assignedto`) VALUES ('" + newAccessCode + "', '0', '')";

    try 
        connection = DBConnections.getAccessCodeDB(AccessCodeDBuser, AccessCodeDBpass, AccessCodeDBhost);
        preparedStatement = connection.prepareStatement(statement);
        results = preparedStatement.executeQuery();

        results.next();

        if(results.getInt(1) == 0) 

         else if(results.getInt(1) >= 1) 
            return 1;
        

        connection = DBConnections.getAccessCodeDB(AccessCodeDBuser, AccessCodeDBpass, AccessCodeDBhost);
        preparedStatement = connection.prepareStatement(statement2);
        preparedStatement.executeUpdate();
        return 2;
     catch (SQLException e) 
        return 0;
    


private static String genAccessCode() 
    randI = ThreadLocalRandom.current().nextInt(min, max + 1);
    randS = randI + "";
    randFinal = StringUtils.toMD5(randS);
    return randFinal;

【问题讨论】:

【参考方案1】:

在 AccessCode() 静态方法中调用了 newAccessCode() 方法 3 次。 将其更改为

public static void AccessCode() 
int newAccessCodeReturn = newAccessCode();
    if(newAccessCodeR`enter code here`eturn  == 0) 
        ServerLogger.writeLog("[ALERT] Database Error");
     else if(newAccessCodeReturn  == 1) 
        //Reruns the code generator, to make a unique code
        newAccessCode();
     else if(newAccessCodeReturn  == 2) 
        ServerLogger.writeLog("[NOTE] New Access Code: " + newAccessCode);
    

【讨论】:

【参考方案2】:

您在if/else if 代码中反复调用newAccessCode()。每次执行此操作时,它都会插入数据库。调用一次并将结果保存在变量中。

int result = newAccessCode();
if(result == 0) 
    ServerLogger.writeLog("[ALERT] Database Error");
 else if(result == 1) 
    //Reruns the code generator, to make a unique code
    newAccessCode();
 else if(result == 2) 
    ServerLogger.writeLog("[NOTE] New Access Code: " + newAccessCode);

或使用switch 声明:

switch (newAccessCode()) 
    case 0:
        ServerLogger.writeLog("[ALERT] Database Error");
        break;
    case 1:
        //Reruns the code generator, to make a unique code
        newAccessCode();
        break;
    case 2:
        ServerLogger.writeLog("[NOTE] New Access Code: " + newAccessCode);
        break;

【讨论】:

【参考方案3】:

每次运行 AccessCode() 函数时,if 语句也会运行该语句。所以不要这样做:

if(newAccessCode() == 0)

您应该将一个新的整数值设置为等于您的 newAccessCode() 函数的值,然后检查 int 的值。

所以:

int returnValue = newAccessCode();

然后检查returnValue的值。

if(returnValue == 0)

这应该可以解决您的问题。

【讨论】:

以上是关于多次插入 SQL 数据库的主要内容,如果未能解决你的问题,请参考以下文章

Oracle SQL 多次插入忽略重复行

c#通过for循环多次向数据库中插入数据。

EF Core 错误地为 Array 执行多次插入

具有可变数量的参数SQL的多次插入

C#,将多行插入 SQL 数据库

sql在具有回滚的事务中多次插入