JSON_CONTAINS не возвращает результат при использовании в подготовленном операторе

#php #sql #json #mariadb #prepared-statement

#php #sql #json #mariadb #подготовленный оператор

Вопрос:

Я пишу подзапрос, чтобы показать определенную информацию из журнала, если отображается символ. Вот моя функция.

 function getcharacterstories($con, $characterid) {
    
    $id = '"'.$characterid.'"';
    
    $sql = "SELECT dtr_entries.entreetitle,
                   dtr_entries.entreeinternallink, 
                   dtr_entries.entreetimestamp
            FROM dtr_entries 
            WHERE JSON_CONTAINS(entreeattachments, ?, '$.character')
            AND dtr_entries.entreetype = 3";
    
    $stmt = mysqli_prepare($con, $sql);
    
    if(!$con->connect_errno) {
                
        $stmt = mysqli_prepare($con, $sql);

        if ($stmt) {

            if (!empty($characterid)) {
                
                mysqli_stmt_bind_param($stmt, 'i' , $id);
                
            }
        
            // shoot it all to the database

            if(!mysqli_stmt_execute($stmt)) {
    
                echo "error in following query:". $sql; 
                                    
                echo 'stmt error: '.mysqli_stmt_error($stmt);

            } else {
                
                mysqli_stmt_bind_result($stmt, $title, $link, $timestamp);

                while (mysqli_stmt_fetch($stmt)){
        
                    echo $title;
        
                }
                
                mysqli_stmt_close($stmt);
                
            }   
            
        } else {
            
            pre($con);
            
            echo $sql; 
                    
            die('mysqli error: '.mysqli_error($con));
            
        }
        
    } else {
        
        die( 'connect error: '.mysqli_connect_error() );
        
    }
    
}
  

Код сам по себе правильный, но возвращает пустой (без ошибок, которые когда-либо были). Когда я запускаю это с числами на панели sql phpmyadmin и использую двойные кавычки вокруг моего значения в json contains, я фактически получаю результат, поэтому я переформатировал characterid в id , но результата все еще нет.

Запрос в phpmyadmin, который выдает результат, выглядит следующим образом.

 SELECT dtr_entries.entreetitle, dtr_entries.entreeinternallink, dtr_entries.entreetimestamp FROM dtr_entries WHERE JSON_CONTAINS(entreeattachments, '"1"', '$.character') AND dtr_entries.entreetype = 3
  

Данные, которые хранятся в столбце entreeattachements, следующие

 {"character":"1","updated-by":"Lazarus","update-time":1599124101}
  

Что я делаю не так и как я могу это исправить?

Это, кстати, 10.2.27 MariaDB.

Комментарии:

1. 1. Включите error_reporting при разработке нового кода, чтобы вы действительно могли видеть сообщения об ошибках. 2. Сообщение об ошибке, вероятно, указывает на то, что вам нужно избежать этого $ , поскольку оно находится в строке с двойными кавычками.

2. Включено сообщение об ошибке @Sammitch. во всех моих файлах я включил команды ini для ведения журнала, и если SQL-запрос оператора содержал бы ошибку, я бы получил результат обратно в виде ошибки. отсюда и все проверки. Более того, журналы ошибок пусты.

3. какую базу данных вы используете Mysql или MariaDB?

4. @VishalSheth 10.2.27 MariaDB. Смотрите основную информацию

Ответ №1:

Проблема

Первоначально $characterid могло быть целое число, но вы бы изменили это здесь:

 $id = '"'.$characterid.'"';
  

и в результате здесь может не быть успешной привязки в виде целого числа:

 mysqli_stmt_bind_param($stmt, 'i' , $id);
  

Возможные решения

Подход 1

Вы могли бы рассмотреть возможность обеспечения привязки в виде строки, как показано ниже

 mysqli_stmt_bind_param($stmt, 's' , $id);
  

Было бы лучше убедиться, что $characterid это действительно целое число, например.

 $id = '"'.intval($characterid).'"';
  

Подход 2

или обновите свой sql, чтобы указать параметр по назначению:

 $sql = "SELECT dtr_entries.entreetitle,
                   dtr_entries.entreeinternallink, 
                   dtr_entries.entreetimestamp
            FROM dtr_entries 
            WHERE JSON_CONTAINS(entreeattachments, '"?"', '$.character')
            AND dtr_entries.entreetype = 3";
  

и использование

 $id = $characterid;
  

Дополнительные ресурсы

Определение, произошла ли ошибка во время привязки —https://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php

Комментарии:

1. я рассмотрю это решение позже сегодня, когда у меня будет доступ к компьютеру, на котором я получил свой код.

2. Warning: mysqli_stmt_bind_param(): Number of variables doesn't match number of parameters in prepared statement in .... Binding parameters failed: (0) Я также добавил сохранение при сбое в привязке, и вы правы, однако оба элемента терпят неудачу, либо когда я пробую оба подхода.

3. Это была цитата в запросе, которая отбросила его, я выбрал решение номер один, но я немного изменил его, но вы направили меня в правильном направлении, спасибо!