Условная вставка MariaDB с заполнителями не работает с PDO - PullRequest
0 голосов
/ 25 апреля 2019

У меня есть следующие таблицы для моего блога:

Таблица tags со столбцами tag_id (AI) и tag

Таблица post_tags со столбцами post_id и tag_id.Он описывает, какие теги принадлежат к каким сообщениям.

Я пытаюсь сделать какой-нибудь SQL-запрос, который привязывает данный tag к данному post_id в post_tags, но если tag не существуетв tags он сначала создает его там.

$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;

Затем у меня есть следующий PHP-код для выполнения этой процедуры:

// 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();

Это должно быть достаточно просто.И действительно, при замене заполнителей на фактические значения и выполнении необработанного запроса из phpMyAdmin это работает!Но когда я выполняю код pdo php, он просто выводит эту ошибку:

string (284) "SQLSTATE [42000]: синтаксическая ошибка или нарушение прав доступа: 1064 В синтаксисе SQL есть ошибка;проверьте руководство, соответствующее вашей версии сервера MariaDB, на предмет правильного синтаксиса, который следует использовать рядом с 'DELIMITER // НАЧАЛО НЕ АТОМНО, ЕСЛИ НЕ СУЩЕСТВУЕТ (ВЫБЕРИТЕ tags. tag ОТ tags' at line 1" Нет необходимости говорить, что это загадочное сообщение об ошибке не имеет значенияиспользовать для меня.

Я использую php 7.3 с 10.1.30-MariaDB-1 ~ xenial

1 Ответ

0 голосов
/ 26 апреля 2019

Я достиг желаемого результата с помощью следующего 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]);
    }
}
...