带占位符的MariaDB条件插入不适用于PDO

时间:2019-04-25 17:43:39

标签: php mysql if-statement pdo mariadb

我的博客有以下表格:

tags包含列tag_id(A.I.)和tag

post_tags,其中具有列post_idtag_id。它描述了哪些标签属于哪些帖子。

我正在尝试进行一些SQL查询,以将给定的tag绑定到post_id中的给定post_tags,但是如果{{1}中不存在tag }}它首先在此处创建。

tags

然后我具有以下PHP代码来执行此过程:

$query = 
SQL
DELIMITER //

BEGIN NOT ATOMIC
    IF NOT EXISTS (SELECT `tags`.`tag` FROM `tags` WHERE `tag`  = :tagname) THEN 
       INSERT INTO `tags` (`tag_id`, `tag`) VALUES (NULL, :tagname);
    END IF;
END //

DELIMITER ;

INSERT INTO post_tags (post_id, tag_id)  SELECT :postid, tags.tag_id FROM tags WHERE tags.tag = :tagname;

这应该足够简单。确实,当替换占位符以获得实际值并从phpMyAdmin内部执行原始查询时,它可以工作!但是当我执行pdo php代码时,它只会转储此错误:

  

string(284)“ SQLSTATE [42000]:语法错误或访问冲突:1064您的SQL语法有错误;请查看与您的MariaDB服务器版本相对应的手册,以在'DELIMITER //附近使用正确的语法/如果不存在则开始非原子(从// all $db variables are given, known and correct. $pdoconn = new PDO("mysql:host=$dbhost;dbname=$db", $dbuser, $dbpass); $pdoconn -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $taginsert = $pdoconn -> prepare($query); $id = 0; // The post_id. This is given, known and correct. $tags = array(); // Array of strings (the tags) foreach ($tags as $tag){ try{ $taginsert -> bindValue(":tagname", $tag, PDO::PARAM_STR); $taginsert -> bindValue(":postid", $id, PDO::PARAM_INT); $taginsert -> execute(); } catch(PDOException $e){ $message = $e->getMessage(); var_dump($message); } } $taginsert -> close(); 中选择tagstag   不用说,这个神秘的错误消息对我没有用。

我将php 7.3与10.1.30-MariaDB-1〜xenial一起使用

1 个答案:

答案 0 :(得分:0)

我通过以下php代码获得了预期的结果:

请记住,这里的错误/边界检查非常少,因为我知道我正在使用的数据集。

$pdo = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
$postid;
$tags = [];
$tagidStmt      = $pdo->prepare("SELECT tag_id FROM tags WHERE tag = :tagname;"); // $tag
$linkExistsStmt = $pdo->prepare("SELECT * FROM post_tags WHERE post_id = :postid AND tag_id = :tagid;"); // $postid, $tagid
$insertionStmt  = $pdo->prepare("INSERT INTO post_tags (post_id, tag_id) VALUES (:postid, :tagid);"); // $postid, $tagid

foreach ($tags as $tag){
    $tagidStmt -> execute(['tagname' => $tag]);
    $tagid = ($tagidStmt -> fetch())["tag_id"];
    $tagid = intval($tagid);

    $linkExistsStmt -> execute(['postid' => $postid, 'tagid' => $tagid]);
    $linkExists = $linkExistsStmt -> fetch();

    if ($linkExists === false){
        $insertion = $insertionStmt -> execute(['postid' => $postid, 'tagid' => $tagid]);
    }
}