Это не группа по выражению - PullRequest
1 голос
/ 20 апреля 2020

Итак, во-первых, я использую ORM для подключения и получения данных из Oracle DB.

Когда я вызываю свою хранимую процедуру из какого-либо инструмента управления базами данных, все работает нормально.

Проблема начинается, когда я хочу запустить это из моего ORM. Выдает ошибку:

ORA-00979: this is not a group by expression.

Обычно это происходит, когда не агрегированные или непостоянные данные не отображаются в группе по клаузуле.

Запрос включается в хранимую процедуру, так что каждый раз, когда я пытаюсь запустить его, он один и тот же, и в нем есть все необходимое в группе по clausule.

Я даже подключаюсь к тому же пользователю oracle. Я также сделал несколько следов, но ничего странного там не было.

Запрос выглядит так:

 for rec in (
select t1.field1,
      t1.field2,
      t1.field3,
      t1.field4,
      t1.field5,
      decode(parameter,'T',nvl(t1.version, '-'),t1.version),
      sum(nvl(t1.liczba2,0)) as left_to_dispatch
    from table_1 t1 
    group by
      t1.field1,
      t1.field2,
      t1.field3,
      t1.field4,
      t1.field5,
      decode(parameter,'T',nvl(t1.version, '-'),t1.version)) 
  loop 
    null; 
  end_loop;

Вопрос: есть ли какие-либо настройки, которые ORM может устанавливать в базе данных (скорее в сеансе) , что может привести к такой ошибке?

Кстати. Я попытался заменить декодирование на случай: я получил ту же ошибку.

Я попытался заменить декодирование на NVL, я получил ту же ошибку.

Но ошибки были только от этого инструмента ORM, когда я пытался запустить его из PL SQL Developer, все работало нормально.

Есть идеи?

PS. Когда я меняю запрос на такой запрос, ORM работает нормально:

for rec in (
    select t1.field1,
          t1.field2,
          t1.field3,
          t1.field4,
          t1.field5,
          t1.version,
          sum(nvl(t1.liczba2,0)) as left_to_dispatch
        from table_1 t1 
        group by
          t1.field1,
          t1.field2,
          t1.field3,
          t1.field4,
          t1.field5,
          t1.version)
      loop 
        null; 
      end_loop;

Ответы [ 3 ]

1 голос
/ 20 апреля 2020

decode() - это старая Oracle функция, которую, возможно, интерпретирует ваш ORM. Почему бы не использовать case вместо этого? Это стандарт SQL, поэтому ORM может быть проще в обработке.

select t1.field1,
      t1.field2,
      t1.field3,
      t1.field4,
      t1.field5,
      case when parameter = 'T' then coalesce(t1.version, '-') else t1.version end,
      sum(nvl(t1.liczba2,0)) as left_to_dispatch
    from table_1 t1 
    group by
      t1.field1,
      t1.field2,
      t1.field3,
      t1.field4,
      t1.field5,
      case when parameter = 'T' then coalesce(t1.version, '-') else t1.version end

Обратите внимание, что я также заменил nvl() на стандартную SQL функцию coalesce(). Нет ничего плохого в использовании старых функций Oracle: Oracle все еще поддерживает их. Тем не менее, они датируются временем, когда Oracle вводил новшества SQL быстрее, чем мог успеть комитет ANSI. Вообще говоря, сторонние инструменты "agnosti c" работают лучше со стандартным SQL, чем со спецификацией продукта c SQL.

1 голос
/ 20 апреля 2020

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

Я также предпочитаю case и coalesce() (стандартные конструкции SQL), поэтому:

select t1.field1, t1.field2, t1.field3, t1.field4, t1.field5, new_version,
       sum(coalesce(t1.liczba2, 0)) as left_to_dispatch
from (select t1.*
             (case when parameter = 'T' then coalesce(t1.version, '-') else t1.version end) as new_version
      from table_1 t1 
     ) t1
group by t1.field1, t1.field2, t1.field3, t1.field4, t1.field5, new_version;
0 голосов
/ 20 апреля 2020

возможно вы забыли запятую после декодирования (параметр, 'T', nvl (t1.version, '-'), t1.version)

decode (параметр, 'T', nvl (t1) .version, '-'), t1.version), сумма (nvl (t1.liczba2,0)) как left_to_dispatch

...