Поле COUNT неверно или синтаксическая ошибка

Какая ошибка, когда я получу следующее сообщение об ошибке

Неустранимая ошибка: исключить исключение "PDOException" с сообщением "SQLSTATE [07002]: [Microsoft] [драйвер ODBC 11 для SQL Server] Поле COUNT неверно или синтаксическая ошибка"...

Это запрос, который я использую

$sql = $pdo->prepare("SELECT stockamount, stockname, stockbalance.stockid, SUM(ABS(reservationtransaction.stockquantity)) AS reservedamount FROM stockbalance
    JOIN stock ON stockbalance.stockid = stock.stockid
    LEFT JOIN reservationtransaction ON reservationtransaction.articleid = :artid
    WHERE stockbalance.articleid = :artid AND ((changeddate > DATEADD(yy,-1,GETDATE()) AND inventorydate > DATEADD(yy,-1,GETDATE())) OR stockbalance.stockamount <> 0)
    GROUP BY stockbalance.stockid");
$sql->bindValue(':artid', $productId);
$sql->execute();

Я искал вопросы в SO, но никто не был подобным или полезным.
Спасибо заранее.

Изменить: Этот запрос отлично работает при выполнении его с помощью Microsoft SQL Server Management Studio, но при использовании PDO я получаю сообщение об ошибке.

Ответ 1

Число параметров, указанных в SQLBindParameter, было меньше количество параметров в выражении SQL, содержащееся в * StatementText. SQLBindParameter вызывается с параметром ParameterValuePtr, установленным на нулевой указатель, StrLen_or_IndPtr не установлен в SQL_NULL_DATA или SQL_DATA_AT_EXEC и InputOutputType не установлены в SQL_PARAM_OUTPUT, поэтому что количество параметров, указанных в SQLBindParameter, было больше, чем количество параметров в выражении SQL, содержащееся в * StatementText. Функция SQLExecute

заполнители должны иметь уникальные имена, даже если они имеют одинаковое значение

$sql = $pdo->prepare("SELECT stockamount, stockname, stockbalance.stockid, SUM(ABS(reservationtransaction.stockquantity)) AS reservedamount FROM stockbalance
JOIN stock ON stockbalance.stockid = stock.stockid
LEFT JOIN reservationtransaction ON reservationtransaction.articleid = :artid
WHERE stockbalance.articleid = :artid2 AND ((changeddate > DATEADD(yy,-1,GETDATE()) AND inventorydate > DATEADD(yy,-1,GETDATE())) OR stockbalance.stockamount <> 0)
GROUP BY stockbalance.stockid");
$sql->bindValue(':artid', $productId);
$sql->bindValue(':artid2', $productId);
$sql->execute();

Ответ 2

Другая возможность, если вы хотите избежать многократного предоставления данных (замените тип данных @artid на правильный тип данных):

$sql = $pdo->prepare("DECLARE @artid int = :artid
    SELECT stockamount, stockname, stockbalance.stockid, SUM(ABS(reservationtransaction.stockquantity)) AS reservedamount FROM stockbalance
    JOIN stock ON stockbalance.stockid = stock.stockid
    LEFT JOIN reservationtransaction ON reservationtransaction.articleid = @artid
    WHERE stockbalance.articleid = @artid AND ((changeddate > DATEADD(yy,-1,GETDATE()) AND inventorydate > DATEADD(yy,-1,GETDATE())) OR stockbalance.stockamount <> 0)
    GROUP BY stockbalance.stockid");
$sql->bindValue(':artid', $productId);
$sql->execute();

Это будет работать только в РСУБД, которая поддерживает инструкции DECLARE.

Ответ 3

Все столбцы, не входящие в какую-либо арифметическую функцию, должны находиться в предложении GROUP BY. см. ниже:

SELECT stockamount, 
       stockname, 
       stockbalance.stockid, 
       Sum(Abs(reservationtransaction.stockquantity)) AS reservedamount 
FROM   stockbalance 
       INNER JOIN stock 
               ON stockbalance.stockid = stock.stockid 
       LEFT JOIN reservationtransaction 
              ON reservationtransaction.articleid = :artid 
WHERE  stockbalance.articleid = :artid 
       AND ( ( changeddate > Dateadd(yy, -1, Getdate()) 
               AND inventorydate > Dateadd(yy, -1, Getdate()) ) 
              OR stockbalance.stockamount <> 0 ) 
GROUP  BY stockamount, 
          stockname, 
          stockbalance.stockid 

Ответ 4

Несмотря на то, что GROUP BY часто является причиной проблемы COUNT, я столкнулся с ошибкой субъекта в SSRS, и это произошло из-за несоответствия между запросом набора данных SSRS и параметрами. Решение состояло в том, чтобы каждый ГДЕ в запросе имел соответствующий параметр для набора данных. (Я пропустил один.)