Что не так с этим составным утверждением? - PullRequest
0 голосов
/ 27 февраля 2019

Я работаю с сервером MySQL Server version: 5.6.42-cll-lve - MySQL Community Server (GPL), и у меня возникают некоторые серьезные проблемы с CONCAT ()

       public function get_urls() {
        // Create query
        $query = "SELECT a.Name, a.PrimaryVersion, e1.URL
        FROM " . $this->table . " a
        INNER JOIN
        FunnelsFlows b ON a.Funnel_ID = b.Funnel_ID
        INNER JOIN
        BackendFlows c ON b.BackendFlow_ID = c.BackendFlow_ID
        INNER JOIN
        BackendLevels d ON CONCAT(c.Level, :lv) = d.BackendLevel_ID
        LEFT JOIN
        BackendPages e1 ON d.Upsell = e1.BackendPage_ID
        LEFT JOIN
        BackendPages e2 ON d.Downsell1 = e2.BackendPage_ID
        LEFT JOIN
        BackendPages e3 ON d.Downsell2 = e3.BackendPage_ID
        WHERE                    
        a.Funnel_ID = :fid 
        LIMIT 0,1";
        // Prepare statement
        $stmt = $this->conn->prepare($query);
        // Bind ID
        $stmt->bindParam(':fid', $this->fid, PDO::PARAM_INT);
        $stmt->bindValue(':lv', $this->lv, PDO::PARAM_STR);
        // Execute query
        $stmt->execute();

При запуске этого кода выдается следующая ошибка: PHP Fatal error: Uncaught PDOException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'c.Level' in 'on clause' in ...

Всю структуру базы данных вы можете посмотреть здесь:
https://app.sqldbm.com/MySQL/Share/wBAF2JMRFFSoPPjIPdYZc0GFrngIE8md_DYjF4jNYw0

Ответы [ 3 ]

0 голосов
/ 27 февраля 2019

Как насчет этого?

$query = "SELECT a.Name, b.URL
        FROM " . $this->table . " a
        INNER JOIN
        FunnelsFlows b ON CONCAT(a.Level, ':lv') = b.Level_ID
        WHERE                
        a.Funnel_ID = :fid 
        LIMIT 0,1";
        // Prepare statement
        $stmt = $this->conn->prepare($query);
        // Bind ID
        $stmt->bindParam(':fid', $this->fid, PDO::PARAM_INT);
        $stmt->bindParam(':lv', $this->lv, PDO::PARAM_INT);
        // Execute query
        $stmt->execute();

Это был быстрый ответ, поэтому я сейчас объясню.

Что я вижу, что вы хотите объединить столбец таблицы со строкой, верно?

Сначала у вас был неправильный идентификатор :level, который вы пытаетесь связать с помощью следующегооператор $stmt->bindParam(':lv', $this->lv, PDO::PARAM_INT);, поэтому вы должны изменить его с помощью :lv или изменить оператор связывания на $stmt->bindParam(':level', $this->lv, PDO::PARAM_INT);.

Второй - при попытке объединить столбец вы должны удалить кавычки, чтобы он былCONCAT('a.Level', и если второй оператор является строкой, он должен быть в одинарных кавычках, поэтому полный оператор CONCAT должен быть записан следующим образом: CONCAT(a.Level, ':lv')

0 голосов
/ 27 февраля 2019

Ваш запрос не может работать так.Вы пытаетесь объединить содержимое поля CONCAT(c.Level, :lv) с параметром :lv.Это приводит к строке, если был столбец Level.Однако вы скорее хотите создать динамическое имя столбца, например Level1 / Level2 aso.

К сожалению, это невозможно сделать с помощью параметров.Это связано с тем, что планы запросов подготовлены.Изменение имен столбцов во время выполнения приведет к изменению плана запроса.

В таком случае необходимо либо создать динамический SQL, либо написать сложное предложение ON.

Предложение ON:

ON 
(
  (:lv = 1 AND c.Level1 = d.BackendLevel_ID)
  OR
  (:lv = 2 AND c.Level2 = d.BackendLevel_ID)
  -- and so on
)

Динамический SQL:

$sql = 'ON (c.Level' . inval($this->lv) . ' = d.BackendLevel_ID)'

Поскольку функция PHP intval считается безопасной, я бы предпочел последний пример для повышения производительности SQL.

0 голосов
/ 27 февраля 2019

Удалить кавычки (как для имени столбца, так и для значения):

CONCAT(a.Level, :level)

Также вы используете неправильное имя параметра:

$stmt->bindParam(':level', $this->lv, PDO::PARAM_INT);
//                 ^^^^^
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...