从数据库读取错误...在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中

时间:2014-07-27 16:31:05

标签: sql sql-server moodle

我有一个Moodle插件,它给了我一些问题。它适用于使用MySQL的服务器,但不适用于MSSQL。当我尝试运行它时,我收到以下错误...

Debug info: SQLState: 42000<br>
Error Code: 8120<br>
Message: [Microsoft][SQL Server Native Client 11.0][SQL Server]Column 'mdl_course.category' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.<br>

SELECT c.*
FROM mdl_course c, mdl_enrol e
WHERE e.courseid = c.id
AND enrol = 'elediamultikeys'
GROUP BY c.id
ORDER BY c.shortname ASC
[array (
)]
Error code: dmlreadexception
Stack trace:

    line 443 of \lib\dml\moodle_database.php: dml_read_exception thrown
    line 250 of \lib\dml\sqlsrv_native_moodle_database.php: call to moodle_database->query_end()
    line 357 of \lib\dml\sqlsrv_native_moodle_database.php: call to sqlsrv_native_moodle_database->query_end()
    line 785 of \lib\dml\sqlsrv_native_moodle_database.php: call to sqlsrv_native_moodle_database->do_query()
    line 833 of \lib\dml\sqlsrv_native_moodle_database.php: call to sqlsrv_native_moodle_database->get_recordset_sql()
    line 50 of \blocks\eledia_multikeys\generate_keys.php: call to sqlsrv_native_moodle_database->get_records_sql()

以下是插件的php文件中的实际代码。有什么我可以改变来使这项工作?谢谢!

// Get all courses which have an elediamultikeys enrol instance.
$sql = "SELECT c.*
    FROM {course} c, {enrol} e
    WHERE e.courseid = c.id
    AND enrol = 'elediamultikeys'
    GROUP BY c.id
    ORDER BY c.shortname ASC";
$courses = $DB->get_records_sql($sql);

编辑sql之后会出现以下情况......

Debug info: SQLState: 42000<br>
Error Code: 156<br>
Message: [Microsoft][SQL Server Native Client 11.0][SQL Server]Incorrect syntax near the keyword 'user'.<br>

INSERT INTO mdl_block_eledia_multikeys (course,code,user,mailedto,timecreated) VALUES('2',N'4ajenabudE',NULL,N'email@gmail.com','1406479511')
[array (
0 => '2',
1 => '4ajenabudE',
2 => NULL,
3 => 'email@gmail.com',
4 => 1406479511,
)]
Error code: dmlwriteexception
Stack trace:

    line 446 of \lib\dml\moodle_database.php: dml_write_exception thrown
    line 250 of \lib\dml\sqlsrv_native_moodle_database.php: call to moodle_database->query_end()
    line 357 of \lib\dml\sqlsrv_native_moodle_database.php: call to sqlsrv_native_moodle_database->query_end()
    line 919 of \lib\dml\sqlsrv_native_moodle_database.php: call to sqlsrv_native_moodle_database->do_query()
    line 1000 of \lib\dml\sqlsrv_native_moodle_database.php: call to sqlsrv_native_moodle_database->insert_record_raw()
    line 151 of \blocks\eledia_multikeys\locallib.php: call to sqlsrv_native_moodle_database->insert_record()
    line 75 of \blocks\eledia_multikeys\generate_keys.php: call to eledia_multikeys_service->create_keylist()

这是第151行的代码

    $newkeys[] = $newkey;
    $newkeyobj = new stdClass();
    $newkeyobj->course = $courseid;
    $newkeyobj->code = $newkey;
    $newkeyobj->user = null;
    $newkeyobj->mailedto = $mail;
    $newkeyobj->timecreated = time();
    $DB->insert_record('block_eledia_multikeys', $newkeyobj);
}

2 个答案:

答案 0 :(得分:0)

您收到该错误的原因是您只将GROUP BY与聚合函数结合使用。

如果您要将其更改为:

// Get all courses which have an elediamultikeys enrol instance.
$sql = "SELECT c.*
    FROM {course} c
     join {enrol} e
       on e.courseid = c.id
    where enrol = 'elediamultikeys'
    ORDER BY c.shortname ASC";
$courses = $DB->get_records_sql($sql);

你不会得到任何错误。

如果输出不符合您的预期,请说明原因,并且可能需要修改查询。

此外,我更改了上面的内容,以便为连接条件使用JOIN子句而不是WHERE子句。这不会导致错误,但语法错误。

想象一下,假设您想要在每门课程中注册的学生人数。您将使用学生的聚合函数(count)和GROUP BY子句按课程分组。然而,当你不是在计算学生,总结其他东西,或在某处做某种聚合时,GROUP BY课程也没有意义。聚合时,GROUP BY才会发挥作用(将2行以上的行转换为1行)。

根据您的编辑,如果INSERT失败的原因是USER列不允许空值(请提供表中的所有约束),您可以尝试以下操作,这将跳过空值 -

// Get all courses which have an elediamultikeys enrol instance.
$sql = "SELECT c.*
    FROM {course} c
     join {enrol} e
       on e.courseid = c.id
    where enrol = 'elediamultikeys'
      and user is not null
    ORDER BY c.shortname ASC";
$courses = $DB->get_records_sql($sql);

答案 1 :(得分:0)

INSERT INTO mdl_block_eledia_multikeys(课程,代码,用户,邮件,时间创建)

将失败,因为user是保留关键字。尝试围绕保留字的括号:

  INSERT INTO mdl_block_eledia_multikeys (course,code,[user],mailedto,timecreated) VALUES('2',N'4ajenabudE',NULL,N'email@gmail.com','1406479511')

甚至更好:重新设计表并避免使用保留关键字作为列名。