无法 运行 准备语句,因为用户变量太长?
Unable to run prepared statement because user variable is too long?
问题
我有一个工作存储过程 (SP),它接受 3 个参数(一个 ID、一个开始日期和一个结束日期)。此 SP 在我的测试系统中运行良好,其中从 GROUP_CONACT
中的 t1.name
返回的所有值都相当短,而 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
设置为局部变量(显然这去掉了 @)但是我在尝试准备代码底部的语句时遇到错误,解释说它不期望局部变量多变的。
代码的用途
该代码用于根据未知数量的结果填充数据透视表 table。这意味着我需要第一个 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>
您需要增加 group_concat_max_len
的值。
为此,您可以 运行
SET GLOBAL group_concat_max_len=..;
但是,一旦您的数据库重新启动,该参数将不再有效。要永久更改 group_concat_max_len
的值,您需要在 my.cnf
文件下添加以下行:
[mysqld]
group_concat_max_len=..
问题
我有一个工作存储过程 (SP),它接受 3 个参数(一个 ID、一个开始日期和一个结束日期)。此 SP 在我的测试系统中运行良好,其中从 GROUP_CONACT
中的 t1.name
返回的所有值都相当短,而 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
设置为局部变量(显然这去掉了 @)但是我在尝试准备代码底部的语句时遇到错误,解释说它不期望局部变量多变的。
代码的用途
该代码用于根据未知数量的结果填充数据透视表 table。这意味着我需要第一个 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>
您需要增加 group_concat_max_len
的值。
为此,您可以 运行
SET GLOBAL group_concat_max_len=..;
但是,一旦您的数据库重新启动,该参数将不再有效。要永久更改 group_concat_max_len
的值,您需要在 my.cnf
文件下添加以下行:
[mysqld]
group_concat_max_len=..