防止在数据库中重复插入

时间:2015-07-17 09:36:43

标签: php mysql phpmyadmin

我将一些数据插入到我的数据库中,这些数据位于两个表中。插入工作正常,但是当我再次尝试插入时,如果单元格有值,则新值将插入其旁边。我尝试了一个if / else条件来阻止新插入,如果单元格中已经有一个值,但是没有使它工作。也许它不是解决方案,或者我做错了。有什么帮助吗?

if(isset($_POST['submit'])) {   
    $degree = $_POST['Degree'];
    $major = $_POST['Major'];
    $univ = $_POST['Univ'];
    $brevet = $_POST['Brevet'];
    $baccbt = $_POST['Baccbt'];
    $selectaf = $_POST['SelectAF'];

    $sql1="SELECT certificatesgrading.brevet,
                  certificatesgrading.baccbt,
                  university.degree,
                  university.major,
                  university.univ
           FROM   university,
                  certificatesgrading
           WHERE  afnumber = '$selectaf'";

    if ($result=mysqli_query($con,$sql1)) {
        // Return the number of rows in result set
        $rowcount=mysqli_num_rows($result);
    }

    $sql="INSERT INTO university
            (afnumber,
             university.degree,
             university.major,
             university.univ)
          VALUES   ('$selectaf',
                    '$degree',
                    '$major',
                    '$univ')";

            $sql1="INSERT INTO certificatesgrading
            (afnumber,
             certificatesgrading.brevet,
             certificatesgrading.baccbt)
             VALUES     ('$selectaf',
                         '$brevet',
                         '$baccbt') ";
            $result = mysql_query($sql);
            $result = mysql_query($sql1);


}
echo $menu;

3 个答案:

答案 0 :(得分:2)

首先,您构建查询的方式非常危险。您从外部源获取原始输入,不进行任何数据验证或转义,并直接在查询字符串中使用它。这就是SQL注入攻击的发生方式。

enter image description here

当你正在使用mysqli时,你真的需要考虑重新实现数据库访问逻辑以使用prepared statements,或者至少开始使用mysqli_real_escape_string()来使你的代码更具抵抗力SQL注入滥用。

至于您的特定问题,我将假设某些列或列的组合必须是唯一的,而其他列不必是唯一的。对于需要唯一的列/组合,您可以创建指示其值不得重复的索引。例如,我假设AFnumber字段是大学的某种识别码,对大学表来说必须是唯一的。如果是这种情况,那么您可以create an index表示此字段必须是唯一的。

CREATE UNIQUE INDEX keep_af_number_unique 
  ON university (AFnumber);

有了这个约束,那么你只能插入一次特定的AFnumber。尝试再次插入相同的值将触发错误(您必须检查并捕获代码!),直到您删除现有的AF编号或更改其值。

如果您有一组列,其中包含的值组合必须是唯一的,您可以跨多个列创建唯一索引

CREATE UNIQUE INDEX multi_col_unique
  ON table_name (column1, column2, column3);

对于三列,现在一个列可以多次保持相同的值,但列的组合必须是唯一的。例如,允许以下数据:

col1 | col2 | col3
===================
   1 |    1 |    1
   2 |    2 |    2
   1 |    1 |    2

但如果您尝试添加值为1, 1, 1的其他行,则会发生错误。

除此之外,在代码中实现一个系统来检测和阻止多个表单提交也是一个好主意,可能是通过使用存储在PHP会话中的令牌。 This question有一些可能有用的解决方案。

答案 1 :(得分:0)

if(isset($_POST['submit']))
{
    $degree = $_POST['degree'];
    $major = $_POST['major'];
    $univ = $_POST['univ'];
    $brevet = $_POST['brevet'];
    $baccbt = $_POST['baccbt'];
    $selectaf = $_POST['selectAF'];

    $sql="SELECT * FROM university,certificatesgrading WHERE AFNumber='$selectaf'";
    $result = mysql_query($sql);
    $count = count($result);

    if($count==0)
    {
        $sql1="INSERT INTO university (AFNumber,university.Degree,university.Major,university.Univ) VALUES('$selectaf','$degree','$major','$univ')";
        $sql2="INSERT INTO certificatesgrading (AFNumber,certificatesgrading.brevet,certificatesgrading.baccbt) VALUES('$selectaf','$brevet','$baccbt')";
        $result1 = mysql_query($sql1);
        $result2 = mysql_query($sql2);
        if(isset($result1) AND isset($result2))
        {
            echo '<script>swal("Success", "Changes have been saved", "success");</script>';
            redirect(base_url() . 'controller/method');//refresh header
        }
        else
        {
            echo 'Something went wrong';
        }
    }

}
  

注意:要使用swal/sweetalert,您需要Download并安装   在$_POST['degree']字段

中查看name变量以大写字母或简单形式开头

答案 2 :(得分:0)

如果你想要涵盖所有可能的情况,这种行为很难自行开发,特别是如果你想处理表之间的关系。

我认为您应该考虑使用doctrine之类的ORM。这样,您就可以在数据模型上修复constraints,由ORM为您处理和检查。还可以考虑将它与像Symfony2这样的PHP框架一起使用。您不必实现完整堆​​栈,根据您的需要,使用某些组件就足够了。

以下是documentation给出的示例以及工作注释:

<?php
/**
 * @Entity
 * @Table(name="ecommerce_products",uniqueConstraints={@UniqueConstraint(name="search_idx", columns={"name", "email"})})
 */
class ECommerceProduct
{
}

使用ORM和框架对于保持PHP数据模型与MySQL模式一致非常有用,因为您将能够非常简单地生成和更新它。 See an exemple on how symfony2 can help here

最后但并非最不重要的一点是,如果您只使用不使用transactions的MySQL语句和innodb之类的引擎,那么您不会考虑并发访问数据,从而导致数据损坏。如果您不需要或想要为整个应用程序实现它,则非常简单地激活并与非事务查询兼容。这是ORM所涵盖的另一个非常重要的方面,你应该真的想到。

相关问题