SQLSTATE [23000]:完整性约束违规:1062密钥“id”的重复条目“0”

时间:2013-06-22 04:31:33

标签: php pdo

遇到问题“ SQLSTATE [23000]:完整性约束违规:1062重复输入'0'用于键'id'”此处,

<? if (!defined("sKEY")) { exit("Houston, We've Got a Problem"); }
class PDOAct
{
    public $db;
    function __construct()
    {
        try {
            $this->db = new PDO(DBdriver.':host='.DBhost.';dbname='.DBbase, DBuser, DBpass);
            $this->db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
        } catch(PDOException $e) {
            $this->err($e->getMessage());
        }
    }
    //
    //
    function select($base, $row, $val, $type)
    {
        try {
            if (isset($row[0]) && isset($val[0]) && isset($type[0]))
            {
                if (isset($base['select']) && $base['select'] != "*")
                {
                    for ($i=0; $i<count($row); $i++)
                    {
                        if ($i < 1)
                        {
                            $q = "SELECT `".$base['select']."` FROM `".$base['table']."` WHERE `".$row[$i]."` = ':".$row[$i]."'";
                        } else {
                            $q = $q." AND `".$row[$i]."` = ':".$row[$i]."'";
                        }
                    }
                } elseif (!isset($base[select]) || $base[select] == "*") {
                    for ($i=0; $i<count($row); $i++)
                    {
                        if ($i < 1)
                        {
                            $q = "SELECT * FROM `".$base['table']."` WHERE `".$row[$i]."` = ':".$row[$i]."'";
                        } else {
                            $q = $q." AND `".$row[$i]."` = ':".$row[$i]."'";
                        }
                    }
                }
            } elseif (!isset($row[0]) && !isset($val[0]) && !isset($type[0])) {
                if ($base['select'] != "" && $base['select'] != "*")
                {
                    $q = "SELECT `".$base['select']."` FROM `".$base['table']."`";
                } elseif ($base['select'] == "" || $base['select'] == "*") {
                    $q = "SELECT * FROM `".$base['table']."`";
                }
            } else {
                exit("Query error!");
            }
            $do = $this->db->prepare($q);
        } catch(PDOException $e) {
            $this->err($e->getMessage());
        }
        $arr = array('do' => $do, 'row' => $row, 'val' => $val, 'type' => $type);
        return $arr;
    }
    //
    //
    function insert($base, $row, $val, $type)
    {
        try {
            if (isset($row[0]) && isset($val[0]) && isset($type[0]))
            {
                for ($i=0; $i<=count($row); $i++)
                {
                    if ($i < 1)
                    {
                        $q = "INSERT INTO `".$base['table']."` (`".$row[$i]."`";
                    } elseif ($i == count($row)) {
                        $q = $q.") VALUES (";
                        for ($j=0; $j<=count($row); $j++)
                        {
                            if ($j < 1)
                            {
                                $q = $q."':".$row[$j]."'";
                            } elseif ($j == count($row)) {
                                $q = $q.")";
                            } else {
                                $q = $q.", ':".$row[$j]."'";
                            }
                        }
                    } else {
                        $q = $q.", `".$row[$i]."`";
                    }
                }
            } else {
                exit("Query error!");
            }
            $do = $this->db->prepare($q);
        } catch(PDOException $e) {
            $this->err($e->getMessage());
        }
        $arr = array('do' => $do, 'row' => $row, 'val' => $val, 'type' => $type);
        return $arr;
    }
    //
    //
    function execute($arr)
    {
        $do = $arr['do'];
        $row = $arr['row'];
        $val = $arr['val'];
        $type = $arr['type'];
        try {
            for ($i=0; $i<count($row); $i++)
            {
                $bindrow = ':'.$row[$i];
                $bindtype = "PDO::PARAM_".strtoupper($type[$i]);
                $do->bindValue($bindrow, $val[$i], $bindtype);
            }
            $do->execute();
        } catch(PDOException $e) {
            $this->err($e->getMessage());
        }
    }
    //
    //
    function err($e)
    {
        file_put_contents('log'.DIR_SEP.'PDOerrors.txt', $e."\n", FILE_APPEND);
        exit("Houston, We've Got a Problem");
    }
}
?>

当我尝试执行这样的插入查询时:

$db = new PDOAct;
    $base   = array("table" => "users");
    $row    = array("id",  "login", "pass",  "level", "date",       "name",  "sex", "birth");
    $val    = array( 4,    "Paul",   135246,   2,     "2013-06-22", "Paulio",  1,    "1996-06-25");
    $type   = array("int", "str",   "int",   "int",   "str",        "str",   "int", "str");
    $res = $db->execute($db->insert($base, $row, $val, $type));
    print_r($res);

在表格中,我有两个id为0&amp;的条目。 1,所以它不能复制id ..
那么问题是什么呢? 谢谢!

1 个答案:

答案 0 :(得分:3)

Dunno为什么还没有人发现它 - 通常会有3到5个人发现像这样的愚蠢的基本语法错误。从查询var_dumped可以清楚地看到它。

最重要的预备语句之一 - 它具有完整格式,而不是部分格式,由PHP人员使用。因此,在使用预准备语句时,不必手动格式化值,以避免双重格式化。

$q .= " AND `".$row[$i]."` = :".$row[$i];

必须是。

请注意,您的功能对SQL注入非常开放。

此外,我发现整套功能都无法使用。我不知道你为什么要把这些有限的SQL子集绑在一起。为什么不写干净的纯SQL?为什么用一些家庭酿造的语法代替它,除了作者之外,任何人都无法阅读?

另请注意,所有这些'休斯顿我们遇到了问题'都是完全没用的。如果你摆脱这个try-catch的东西,PHP将完成所有记录和退出工作并告诉问题,并且比你的代码做得更好。

我该怎么做:

$db   = new safeMysql();
$data = array("id" => 4, "login" => "Paul", "pass" => 135246, "level" => 2, 
              "date" => "2013-06-22", "name" => "Paulio",  "sex" => 1, 
              "birth"=> "1996-06-25");
$db->query("INSERT INTO users SET ?u", $data);

看,我保持SQL自然,这使我的查询灵活。如果我需要INSERT IGNORE怎么办?或REPLACE代替INSERT?通过我的方法,我将在查询中更改一个单词。虽然你将深入解决问题。对于SELECT查询,它会更麻烦。