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

Проблема

У меня есть рабочая хранимая процедура (SP), которая принимает 3 параметра (идентификатор, от даты и до даты). Этот SP отлично работает в моей тестовой системе, где все значения возвращаются из t1.name в GROUP_CONACT довольно короткие и не так много в GROUP_CONCAT,

Проблема в том, что когда я добавляю это в систему LIVE, есть еще несколько вопросов, которые можно добавить к GORUP_CONCAT и t1.name значения намного длиннее, чем ожидалось.

Из результатов, которые я вижу при попытке отладки скрипта, видно, что проблема в том, что переменная @SQL не может хранить всю информацию, предоставленную обратно из GROUP_CONACT запрос.

Код

CREATE DEFINER=`root`@`localhost` PROCEDURE `team_analyst_results`(in var1 int, in var2 DATE, in var3 DATE)
BEGIN


  SELECT
      GROUP_CONCAT(DISTINCT CONCAT('MAX(IF(question_id = \'',
                  question_id,
                  '\', Pass, Null)) AS ',
                  CONCAT('\'', t1.name, '\'')))
  INTO @SQL FROM
      smhubdb.questions t1
          INNER JOIN
      smhubdb.check_questions t2 ON t1.id = t2.question_id
          INNER JOIN
      smhubdb.quality_checks t3 ON t2.check_id = t3.id
          INNER JOIN
      smhubdb.users t4 ON t3.check_person = t4.id
  WHERE
      t4.team_id = var1
  AND
    t3.checked_date BETWEEN var2 AND var3
  GROUP BY t3.check_person;

  SET @SQL = CONCAT('SELECT t1.id AS "'"Check ID"'", t4.name AS "'"Name"'" ,DATE_FORMAT(t1.checked_date, "'"%d-%m-%Y"'") AS "'" Check Date "'" , ', @SQL, ' , t1.notes AS "'"Notes"'", CONCAT(ROUND((SUM(CASE WHEN t2.pass = 1 THEN t3.value ELSE 0 END) / SUM(t3.value) * 100),0),"'""'") AS "'"Score"'" FROM smhubdb.quality_checks t1 LEFT JOIN smhubdb.check_questions t2 ON t1.id = t2.check_id LEFT JOIN smhubdb.questions t3 on t2.question_id = t3.id INNER JOIN smhubdb.users t4 ON t1.check_person = t4.id WHERE t4.team_id = ''', var1 ,''' AND t1.checked_date BETWEEN ''', var2 ,''' AND ''', var3 ,''' GROUP BY t1.id ORDER BY t1.id DESC');


  PREPARE stmt FROM @SQL;
  EXECUTE stmt;
END

Что я пробовал

Я пытался установить @SQL как локальная переменная (очевидно, это отбросило @), но затем я получаю ошибку при попытке подготовить оператор в нижней части кода, объясняя, что она не ожидает локальной переменной.

Назначение кода

Код используется для заполнения сводной таблицы с неизвестным количеством результатов. Это означает, что мне нужно первое GROUP_CONCAT раздел для построения имен столбцов в конце оператора для подготовки.

Ожидаемый результат

Количество вопросов не будет известно, равно как и название вопроса.

table, td, th {
 border: 1px solid black;
}

table {
 border-collapse: collapse;
}
<table>
<thead>
<th>
Name
</th>
<th>
Check ID
</th>
<th>
Date
</th>
<th>
Question1
</th>
<th>
Question2
</th>
<th>
Question3
</th>
<th>
Question4
</th>
<th>
Notes
</th>
<th>
Score
</th>
</thead>
<tbody>
<tr>
<td>
Joe Bloggs
</td>
<td>
1
</td>
<td>
08/11/2018
</td>
<td>
Pass
</td>
<td>
Pass
</td>
<td>
Null
</td>
<td>
Pass
</td>
<td>
Some Notes
</td>
<td>
75%
</td>
<tr>
</tbody>
</table>

1 ответ

Решение

Вам нужно увеличить стоимость group_concat_max_len, Для этого вы можете запустить

SET GLOBAL group_concat_max_len=..;

Однако после перезапуска базы данных этот параметр больше не будет действовать. Чтобы навсегда изменить значение group_concat_max_len, вам нужно добавить следующую строку под my.cnf файл:

[mysqld]
group_concat_max_len=..
Другие вопросы по тегам