使用 mysql_query() PHP 执行 INSERT 语句时出现问题


issue performing an INSERT statement with mysql_query() PHP

基本上,我正在尝试在我的一个PHP类中实现一个函数,该函数进入many to many关系的联结表。

这是这里的方法:

public function setTags($value, $id){
    global $db;
    $tags = $value;
    $query .= "DELETE FROM directorycolumntags 
               WHERE directorycolumn_id = $id; ";
    foreach($tags as $tag){
    $query .= "INSERT INTO directorycolumntags (directorycolumn_id, tag_id)
               VALUES (".$id.",".$tag.");";
    }   
    mysql_query($query);
}

SQL是产生工作正常,因为我已经回显了它并通过phpMyAdmin手动执行它。但是,如果我将其保留为上述内容,则永远不会插入数据。有谁知道为什么会发生这种情况?

这是它生成的sql,当我手动输入它时工作正常:

DELETE FROM directorycolumntags WHERE directorycolumn_id = 178; 
INSERT INTO directorycolumntags (directorycolumn_id, tag_id) VALUES (178,29);
INSERT INTO directorycolumntags (directorycolumn_id, tag_id) VALUES (178,30);
INSERT INTO directorycolumntags (directorycolumn_id, tag_id) VALUES (178,32);
旧的

、不安全的、已弃用的mysql_*扩展从不支持多个查询。可以想象,您可以使用mysql替换扩展来执行此操作:mysqli_* ,它具有mysqli_multi_query功能。
不过,就个人而言,我不会使用这种方法。我会做大多数开发人员会做的事情:在事务中使用预准备语句来安全地执行每个查询,并在成功时提交结果,或在失败时回滚:

$db = new PDO(
    'mysql:host=127.0.0.1;dbname=db;charset=utf8',
    'user',
    'pass',
    array(
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
    )
);
try
{
    $db->beginTransaction();
    $stmt = $db->prepare('DELETE FROM tbl WHERE field = :id');
    $stmt->execute(array(':id' => $id));
    $stmt = $db->prepare('INSERT INTO tbl (field1, field2) VALUES (:field1, :field2)');
    foreach ($tags as $tag)
    {
        $stmt->execute(
            array(
                ':field1' => $id,
                ':field2' => $tag
            )
        );
        $stmt->closeCursor();//<-- optional for MySQL
    }
    $db->commit();
}
catch (PDOException $e)
{
    $db->rollBack();
    echo 'Something went wrong: ', $e->getMessage();
}

稍微跑题了:你真的应该考虑使用类型提示。从您的代码中可以清楚地看出$values应该是一个数组。类型提示可以确保传递的值实际上是一个数组。你也应该摆脱那个丑陋的global $db;,而是将连接作为参数传递。这就是为什么我强烈建议您将函数的签名从:

public function setTags($value, $id){

自:

public function setTags(PDO $db, array $value, $id)
{
}

这样,调试就变得容易多了:

$instance->setTags(123, 123);//in your current code will not fail immediately
$instance->setTags($db, [123], 123);//in my suggestion works but...
$instance->setTags([123], null, '');// fails with a message saying argument 1 instance of PDO expected

http://docs.php.net/mysql_query 说:

mysql_query() sends a unique query (multiple queries are not supported) to the currently active database on the server that's associated with the specified link_identifier 
如果你可以使用mysqli

,也许你会对此感兴趣:mysqli.multi-query

Executes one or multiple queries which are concatenated by a semicolon.
你不能

使用mysql_query运行多个quires,试着像这样修改你的函数。如果您使用 mysqli 或 pdo 而不是 mysql,那就更好了,因为很快它就会被弃用,并且无法在较新版本的 php 上运行

public function setTags($value, $id){
    global $db;
    $tags = $value;
    mysql_query("DELETE FROM directorycolumntags WHERE directorycolumn_id = $id");
    foreach($tags as $tag){
        mysql_query("INSERT into directorycolumntags (directorycolumn_id, tag_id) VALUES (".$id.",".$tag.")");
    }   
}