简体   繁体   中英

issue performing an INSERT statement with mysql_query() PHP

basically I am trying to implement a function in one of my PHP classes that makes an entry into a junction table for a many to many relationship.

This is the method here:

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);
}

The SQL is produces works fine, as I've echoed it and manually executed it via phpMyAdmin . However, If I leave it as above, the data is never inserted. Does anyone know why this might be happening?

This is the sql it is generating which works fine when I type it manually in:

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 says:

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 

If you can use mysqli perhaps this interest you: mysqli.multi-query

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

The old, unsafe, deprecated mysql_* extension never supported multiple queries. You could , conceivably do this using the mysql replacement extension: mysqli_* , which has the mysqli_multi_query function .
Personally, I'd not use this approach, though. I'd do what most devs would do: use a prepared statement in a transaction to execute each query safely, and commit the results on success, or rollback on failure:

$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();
}

Going slightly off-topic: You really ought to consider using type-hints. From your code, it's clear that $values is expected to be an array. A type-hint can ensure that the value being passed is in fact an array. You should also get rid of that ugly global $db; , and instead pass the connection as an argument, too. That's why I'd strongly suggest you change your function's signature from:

public function setTags($value, $id){

To:

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

That way, debugging gets a lot easier:

$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

you can not run multiple quires using mysql_query, try to modify your function like this. It would be better if you use mysqli or pdo instead of mysql because soon it will deprecated and it would not work on newer version of 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.")");
    }   
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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