插入表中的重复数据集

时间:2018-01-28 16:12:20

标签: php mysql arrays loops

为什么这段代码会插入重复的数据集?

这里传递给函数的$franchises数组(2 = count($franchises)):

(
    [0] => Array
        (
            [franchise_id] => 3
            [franchisor_id] => 3
            [franchise_name] => Fitness Freaks
        )

    [1] => Array
        (
            [franchise_id] => 4
            [franchisor_id] => 3
            [franchise_name] => Gyms Galore
        )

)

这是使用for loop将数据插入表中的函数:

public static function setLeadData($franchises)
{
   try
   {
        $db = static::getDB();

        $sql = "INSERT INTO leads_franchises SET
               franchise_id    = :franchise_id,
               franchisor_id   = :franchisor_id,
               franchise_name  = :franchise_name";
        $stmt = $db->prepare($sql);

        for($i = 0; $i < count($franchises); $i++)
        {
            $result = $stmt->execute([
                ':franchise_id'   => $franchises[$i]['franchise_id'],
                ':franchisor_id'  => $franchises[$i]['franchisor_id'],
                ':franchise_name' => $franchises[$i]['franchise_name']
            ]);
        }

        return $result;
    }
    catch(PDOException $e)
    {
        echo $e->getMessage();
        exit();
    }
}

这里使用foreach loop的功能相同。它还插入重复的数据集(数组为1个插入2个相同的行,计数为2个插入2组相同的行,3个插入6等):

public static function setLeadData($franchises)
{
   try
   {
        $db = static::getDB();

        $sql = "INSERT INTO leads_franchises SET
               franchise_id    = :franchise_id,
               franchisor_id   = :franchisor_id,
               franchise_name  = :franchise_name";
        $stmt = $db->prepare($sql);

        foreach($franchises as $franchise)
        {
            $result = $stmt->execute([
                ':franchise_id'   => $franchise['franchise_id'],
                ':franchisor_id'  => $franchise['franchisor_id'],
                ':franchise_name' => $franchise['franchise_name']
            ]);
        }

        return $result;
    }
    catch(PDOException $e)
    {
        echo $e->getMessage();
        exit();
    }
}

这里是foreach loop

中MySQL组件的功能
public static function setLeadData($franchises)
{
   try
   {
        $db = static::getDB();

        foreach($franchises as $franchise)
        {
            $sql = "INSERT INTO leads_franchises SET
                   franchise_id    = :franchise_id,
                   franchisor_id   = :franchisor_id,
                   franchise_name  = :franchise_name";
            $stmt = $db->prepare($sql);
            $result = $stmt->execute([
                ':franchise_id'   => $franchise['franchise_id'],
                ':franchisor_id'  => $franchise['franchisor_id'],
                ':franchise_name' => $franchise['franchise_name']
            ]);
        }

        return $result;
    }
    catch(PDOException $e)
    {
        echo $e->getMessage();
        exit();
    }
}

此处有stmt = $db->prepare($sql)内的foreach loop功能:

public static function setLeadData($franchises)
{
   try
   {
        $db = static::getDB();

        $sql = "INSERT INTO leads_franchises SET
               franchise_id    = :franchise_id,
               franchisor_id   = :franchisor_id,
               franchise_name  = :franchise_name";

        foreach($franchises as $franchise)
        {                
            $stmt = $db->prepare($sql);
            $result = $stmt->execute([
                ':franchise_id'   => $franchise['franchise_id'],
                ':franchisor_id'  => $franchise['franchisor_id'],
                ':franchise_name' => $franchise['franchise_name']
            ]);
        }

        return $result;
    }
    catch(PDOException $e)
    {
        echo $e->getMessage();
        exit();
    }
}

(编辑添加):此处使用bindParam内的foreach loop功能:

public static function setLeadData($franchises)
{

    try
    {
        $db = static::getDB();

        $sql = "INSERT INTO leads_franchises (franchise_id, franchisor_id, franchise_name)
                VALUES (:franchise_id, :franchisor_id, :franchise_name)";

        $stmt = $db->prepare($sql);

        foreach($franchises as $franchise)
        {
            $stmt->bindParam(':franchise_id', $franchise['franchise_id']);
            $stmt->bindParam(':franchisor_id', $franchise['franchisor_id']);
            $stmt->bindParam(':franchise_name', $franchise['franchise_name']);

            $result = $stmt->execute();
        }

        return $result;
    }
    catch(PDOException $e)
    {
        echo $e->getMessage();
        exit();
    }
}

每个版本都会产生相同的重复。

显然,我非常沮丧。我非常希望了解此代码导致重复的原因和方式。

非常感谢任何帮助!

函数执行后的表:

enter image description here

更新

为了帮助可能遇到此问题的任何人,我想发布重复的原因。正如Ermat Kiyomov所证明的那样,功能代码是正确的。

错误发生在Ajax代码中。表格提交了两次。 Chris Sercombe提供的解决方案是here.

e.preventDefault()外,我还需要添加e.stopImmediatePropagationMore info here.

jQuery Ajax的提交部分如下所示:

$("#form").submit(function(e) {
    e.preventDefault();
    e.stopImmediatePropagation();

    ....

1 个答案:

答案 0 :(得分:2)

我测试了以下样本,没有发生重复:

class Franchises
{
    protected static function getDB()
    {
        $conn = NULL;

        try
        {
            $conn = new PDO("mysql:host=127.0.0.1;dbname=franchises_db", "dbuser", "dbpassword");
            $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        }
        catch(PDOException $e)
        {
            echo $e->getMessage();
            exit();
        }
        return $conn;
    } 
    public static function setLeadData($franchises)
    {
       try
       {
            $db = static::getDB();

            $sql = "INSERT INTO leads_franchises SET
                   franchise_id    = :franchise_id,
                   franchisor_id   = :franchisor_id,
                   franchise_name  = :franchise_name";
            $stmt = $db->prepare($sql);

            foreach($franchises as $franchise)
            {
                $result = $stmt->execute([
                    ':franchise_id'   => $franchise['franchise_id'],
                    ':franchisor_id'  => $franchise['franchisor_id'],
                    ':franchise_name' => $franchise['franchise_name']
                ]);
            }

            return $result;
        }
        catch(PDOException $e)
        {
            echo $e->getMessage();
            exit();
        }
    }
}

$vals = [
    [
        "franchise_id" => 3,
        "franchisor_id" => 3,
        "franchise_name" => "Fitness Freaks"
    ],
    [
        "franchise_id" => 4,
        "franchisor_id" => 3,
        "franchise_name" => "Gyms Galore"
    ]
];

Franchises::setLeadData($vals);

和leads_franchises表创建代码是:

CREATE TABLE `leads_franchises` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `franchise_id` INT(11) NULL DEFAULT '0',
    `franchisor_id` INT(11) NULL DEFAULT '0',
    `franchise_name` VARCHAR(128) NULL DEFAULT '',
    PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;