繁体   English   中英

使用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);

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_*使用的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

您不能使用mysql_query运行多个查询,请尝试像这样修改您的函数。 如果您使用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.")");
    }   
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM