MySQL Query терпит неудачу через PHP PDO, успешно через phpMyAdmin - PullRequest
0 голосов
/ 16 апреля 2019

Я создаю запрос для возврата высокой / узкой таблицы в «широком» формате (в итоге получается CSV).

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

SELECT
  CONV(a.assetID, 10, 16) AS assetID,
  a.notes,
  a.budgetReplaceDate,
  p.propertyName AS property,
  b.buildingName AS building,
  MAX(IF(ad.fieldID = ?, ad.text, NULL)) AS ?,
  MAX(IF(ad.fieldID = ?, ad.text, NULL)) AS ?,
  MAX(IF(ad.fieldID = ?, ad.text, NULL)) AS ?,
  MAX(IF(ad.fieldID = ?, ad.text, NULL)) AS ?,
  MAX(IF(ad.fieldID = ?, c.choice, NULL)) AS ?,
  MAX(IF(ad.fieldID = ?, ad.text, NULL)) AS ?
FROM
  asset_details AS ad
  INNER JOIN assets AS a ON a.assetID = ad.assetID
  LEFT JOIN asset_choices AS c ON c.choiceID = ad.choiceID
  LEFT JOIN property AS p ON a.propertyID = p.propertyID
  LEFT JOIN property_buildings AS b ON a.buildingID = b.buildingID
WHERE
  a.clientID IN(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
  AND a.formID = ?
  AND (
    a.deletedID IS NULL
    OR a.deletedID = 0
  )
GROUP BY
  assetID
ORDER BY
  assetID
LIMIT
  10 OFFSET 0

И параметры, которые я передаю, следующие:

array(29) {
    [0]=> string(3) "385"
    [1]=> string(4) "f385"
    [2]=> string(3) "386"
    [3]=> string(4) "f386"
    [4]=> string(3) "387"
    [5]=> string(4) "f387"
    [6]=> string(3) "388"
    [7]=> string(4) "f388"
    [8]=> string(3) "389"
    [9]=> string(4) "f389"
    [10]=> string(3) "390"
    [11]=> string(4) "f390"
    [12]=> string(2) "14"
    [13]=> string(2) "15"
    [14]=> string(2) "26"
    [15]=> string(2) "29"
    [16]=> string(2) "30"
    [17]=> string(2) "31"
    [18]=> string(2) "32"
    [19]=> string(2) "34"
    [20]=> string(2) "35"
    [21]=> string(2) "36"
    [22]=> string(2) "37"
    [23]=> string(2) "38"
    [24]=> string(2) "39"
    [25]=> string(2) "40"
    [26]=> string(2) "41"
    [27]=> string(2) "42"
    [28]=> string(2) "41"
}

При попытке выполнить его через PDO в PHP я получаю следующую ошибку:

Предупреждение: PDOStatement :: execute (): SQLSTATE [42000]: синтаксическая ошибка или нарушение прав доступа: 1064 В синтаксисе SQL имеется ошибка;проверьте руководство, соответствующее вашей версии сервера MySQL, чтобы узнать правильный синтаксис для использования рядом с «SELECT CONV (a.assetID, 10, 16) AS assetID, a.notes, a.budgetReplaceDate» в строке 1 в report.php в строке580

Если я иду и вручную копирую и вставляю каждое из значений в массиве в правильное место в запросе и запускаю его через phpMyAdmin (или adminer), это работает правильно.

Я думал, что это может быть эта часть:

  MAX(IF(ad.fieldID = ?, ad.text, NULL)) AS ?,
  MAX(IF(ad.fieldID = ?, ad.text, NULL)) AS ?,
  MAX(IF(ad.fieldID = ?, ad.text, NULL)) AS ?,
  MAX(IF(ad.fieldID = ?, ad.text, NULL)) AS ?,
  MAX(IF(ad.fieldID = ?, c.choice, NULL)) AS ?,
  MAX(IF(ad.fieldID = ?, ad.text, NULL)) AS ?

, но у меня есть упрощенная версия запроса, которая прекрасно с этим работает.Я не могу на всю жизнь понять, что происходит.Чего мне не хватает?

Ниже общий журнал:

Tcp port: 3306  Unix socket: /var/run/mysqld/mysqld.sock
Time                 Id Command    Argument
2019-04-11T08:54:26.499114Z 376072 Connect  *USERNAME*@localhost on *DATABASE* using TCP/IP
2019-04-11T08:54:26.499374Z 376072 Query    SELECT sessionID, uid, loginDate, lastActive, ipAddress FROM session WHERE loggedOut = 0 AND token = '*REDACTED*' AND lastActive >= '2019-04-10 15:54:26' - INTERVAL 27 HOUR
2019-04-11T08:54:26.499889Z 376073 Connect  *USERNAME*@localhost on *DATABASE* using TCP/IP
2019-04-11T08:54:26.500007Z 376073 Query    SELECT userID, userEmail, userLevel, userGroupID, joinDate, firstname, lastname, subscriptionEndDate, contactNo, contractorID, homePropertyID, timezone, uuid FROM users WHERE userID = '2'
2019-04-11T08:54:26.500487Z 376074 Connect  *USERNAME*@localhost on *DATABASE* using TCP/IP
2019-04-11T08:54:26.500595Z 376074 Query    SELECT * FROM userGroups WHERE userGroupID = '1'
2019-04-11T08:54:26.500891Z 376073 Query    SELECT ClientID FROM client
2019-04-11T08:54:26.501095Z 376073 Quit 
2019-04-11T08:54:26.501180Z 376072 Query    UPDATE session SET lastActive = '2019-04-11 18:54:26', browser = NULL WHERE sessionID = '2691'
2019-04-11T08:54:26.503173Z 376074 Query    SELECT * FROM markers
2019-04-11T08:54:26.503416Z 376072 Quit 
2019-04-11T08:54:26.503954Z 376074 Query    SELECT f.formID, f.formName, f.formTable, f.category, f.budget, s.formName AS srvcName, s.formID AS srvcFormID, s.formTable AS srvcTable, s.srvcFreq AS freq FROM forms as f
            LEFT JOIN srvcForms AS s ON f.formID = s.assetTable WHERE f.formID = '41' LIMIT 1
2019-04-11T08:54:26.504237Z 376074 Query    SELECT * FROM formField WHERE formID = '41' ORDER BY position, fieldID
2019-04-11T08:54:26.504948Z 376074 Query    SELECT 
    CONV(a.assetID, 10, 16) AS assetID,
    a.notes,
    a.budgetReplaceDate,
    p.propertyName AS property,
    b.buildingName AS building
    ,
    MAX(IF(ad.fieldID = '385', ad.text, NULL)) AS 'f385',
    MAX(IF(ad.fieldID = '386', ad.text, NULL)) AS 'f386',
    MAX(IF(ad.fieldID = '387', ad.text, NULL)) AS 'f387',
    MAX(IF(ad.fieldID = '388', ad.text, NULL)) AS 'f388',
    MAX(IF(ad.fieldID = '389', c.choice, NULL)) AS 'f389',
    MAX(IF(ad.fieldID = '390', ad.text, NULL)) AS 'f390'
FROM asset_details AS ad
INNER JOIN assets AS a ON a.assetID = ad.assetID
LEFT JOIN asset_choices AS c ON c.choiceID = ad.choiceID
LEFT JOIN property AS p ON a.propertyID = p.propertyID
LEFT JOIN property_buildings AS b ON a.buildingID = b.buildingID

WHERE a.clientID IN('14', '15', '26', '29', '30', '31', '32', '34', '35', '36', '37', '38', '39', '40', '41', '42') AND a.formID = '41' AND (a.deletedID IS NULL OR a.deletedID = 0)
GROUP BY assetID ORDER BY assetID LIMIT 10 OFFSET 0
2019-04-11T08:54:26.512918Z 376074 Quit 
2019-04-11T08:54:32.938734Z 376067 Query    set global general_log = "OFF"

Ответы [ 2 ]

1 голос
/ 16 апреля 2019

Нельзя использовать ? заполнители для указания псевдонима столбца в подготовленном операторе MySQL. Итак, вы должны просто использовать жестко заданные псевдонимы:

SELECT
    CONV(a.assetID, 10, 16) AS assetID,
    a.notes,
    a.budgetReplaceDate,
    p.propertyName AS property,
    b.buildingName AS building,
    MAX(IF(ad.fieldID = ?, ad.text, NULL)) AS max_one,
    MAX(IF(ad.fieldID = ?, ad.text, NULL)) AS max_two,
    MAX(IF(ad.fieldID = ?, ad.text, NULL)) AS max_three,
    MAX(IF(ad.fieldID = ?, ad.text, NULL)) AS max_four,
    MAX(IF(ad.fieldID = ?, c.choice, NULL)) AS max_five,
    MAX(IF(ad.fieldID = ?, ad.text, NULL)) AS max_six
  FROM asset_details AS ad
  -- the rest of your query the same

Но я не вижу веской причины для контроля псевдонимов, как вы думаете. Вашему PHP-сценарию также, вероятно, понадобится жестко закодированное уже известное имя псевдонима для извлечения значения.

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

Оказывается, это действительно работало, это была ошибка в дальнейшем.

Я переписываю существующую функцию и не заметил, что функция повторно использовала SQL-запрос, чтобы выполнить подсчет общего количества записей (чтобы показать «Просмотр 1-10 из 1000»). ошибка была на самом деле с этим и была быстро легко исправить.

Извлеченный урок, НАЧАЛЬНО ПРОВЕРЬТЕ НОМЕР ЛИНИИ, НА КОТОРЫЙ ОШИБКА ВКЛЮЧЕНА!

Если честно, у меня была пара опечаток для начала, просто я не заметил, когда изменился номер строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...