Ошибка (ORA-00923: ключевое слово FROM не найдено, где ожидалось) для LISTAGG [duplicate]

Что такое NullPointerException?

Хорошим местом для начала является JavaDocs . Они охватывают это:

Брошено, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  • Вызов метода экземпляра нулевого объекта.
  • Доступ или изменение поля нулевого объекта.
  • Выполнение длины null, как если бы это был массив.
  • Доступ или изменение слотов с нулевым значением, как если бы это был массив.
  • Бросать нуль, как если бы это было значение Throwable.

Приложения должны бросать экземпляры этого класса для указания других незаконных видов использования нулевого объекта.

Также, если вы попытаетесь использовать нулевую ссылку с synchronized, который также выдаст это исключение, за JLS :

SynchronizedStatement:
    synchronized ( Expression ) Block
  • В противном случае, если значение выражения равно null, NullPointerException.

Как это исправить?

Итак, у вас есть NullPointerException. Как вы это исправите? Возьмем простой пример, который выдает NullPointerException:

public class Printer {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public void print() {
        printString(name);
    }

    private void printString(String s) {
        System.out.println(s + " (" + s.length() + ")");
    }

    public static void main(String[] args) {
        Printer printer = new Printer();
        printer.print();
    }
}

Идентифицирует нулевые значения

. Первый шаг - точно определить , значения которого вызывают исключение . Для этого нам нужно выполнить некоторую отладку. Важно научиться читать stacktrace . Это покажет вам, где было выбрано исключение:

Exception in thread "main" java.lang.NullPointerException
    at Printer.printString(Printer.java:13)
    at Printer.print(Printer.java:9)
    at Printer.main(Printer.java:19)

Здесь мы видим, что исключение выбрано в строке 13 (в методе printString). Посмотрите на строку и проверьте, какие значения равны нулю, добавив протоколирующие операторы или используя отладчик . Мы обнаруживаем, что s имеет значение null, а вызов метода length на него вызывает исключение. Мы видим, что программа перестает бросать исключение, когда s.length() удаляется из метода.

Трассировка, где эти значения взяты из

Затем проверьте, откуда это значение. Следуя вызовам метода, мы видим, что s передается с printString(name) в методе print(), а this.name - null.

Трассировка, где эти значения должны быть установлены

Где установлен this.name? В методе setName(String). С некоторой дополнительной отладкой мы видим, что этот метод вообще не вызывается. Если этот метод был вызван, обязательно проверьте порядок , что эти методы вызывают, а метод set не будет называться после методом печати. ​​

Этого достаточно, чтобы дать нам решение: добавить вызов printer.setName() перед вызовом printer.print().

Другие исправления

Переменная может иметь значение по умолчанию setName может помешать ему установить значение null):

private String name = "";

Либо метод print, либо printString может проверить значение null например:

printString((name == null) ? "" : name);

Или вы можете создать класс, чтобы name всегда имел ненулевое значение :

public class Printer {
    private final String name;

    public Printer(String name) {
        this.name = Objects.requireNonNull(name);
    }

    public void print() {
        printString(name);
    }

    private void printString(String s) {
        System.out.println(s + " (" + s.length() + ")");
    }

    public static void main(String[] args) {
        Printer printer = new Printer("123");
        printer.print();
    }
}

См. также:

Я все еще не могу найти проблему

Если вы попытались отладить проблему и до сих пор не имеете решения, вы можете отправить вопрос для получения дополнительной справки, но не забудьте включить то, что вы пробовали до сих пор. Как минимум, включите stacktrace в вопрос и отметьте важные номера строк в коде. Также попробуйте сначала упростить код (см. SSCCE ).

117
задан Luv 7 October 2013 в 06:01
поделиться

14 ответов

С предложением модели SQL:

SQL> select pid
  2       , ltrim(sentence) sentence
  3    from ( select pid
  4                , seq
  5                , sentence
  6             from b
  7            model
  8                  partition by (pid)
  9                  dimension by (seq)
 10                  measures (descr,cast(null as varchar2(100)) as sentence)
 11                  ( sentence[any] order by seq desc
 12                    = descr[cv()] || ' ' || sentence[cv()+1]
 13                  )
 14         )
 15   where seq = 1
 16  /

P SENTENCE
- ---------------------------------------------------------------------------
A Have a nice day
B Nice Work.
C Yes we can do this work!

3 rows selected.

Я написал об этом здесь . И если вы перейдете по ссылке на поток OTN, вы найдете еще несколько примеров, включая сравнение производительности.

171
ответ дан Dave Jarvis 18 August 2018 в 06:53
поделиться
  • 1
    используя wm_concat () для Oracle 10g, конкатенация текста в порядке возрастания порядкового номера, разделенного запятыми, можем ли мы опускать разграничение на что-то еще? – jagamot 7 March 2011 в 22:01
173
ответ дан Dave Jarvis 6 September 2018 в 20:37
поделиться
177
ответ дан Dave Jarvis 30 October 2018 в 01:56
поделиться

Аналитическая функция LISTAGG была введена в Oracle 11g Release 2 , что упрощает агрегацию строк. Если вы используете 11g Release 2, вы должны использовать эту функцию для агрегации строк. Пожалуйста, обратитесь к url ​​для получения дополнительной информации о конкатенации строк.

http://www.oracle-base.com/articles/misc/StringAggregationTechniques.php

Конкатенация строк

6
ответ дан Ashish J 18 August 2018 в 06:53
поделиться

В выборе, где вы хотите выполнить конкатенацию, вызовите функцию SQL.

Например:

select PID, dbo.MyConcat(PID)
   from TableA;

Затем для функции SQL:

Function MyConcat(@PID varchar(10))
returns varchar(1000)
as
begin

declare @x varchar(1000);

select @x = isnull(@x +',', @x, @x +',') + Desc
  from TableB
    where PID = @PID;

return @x;

end

Синтаксис заголовка функции может быть неправильным, но принцип работает.

-3
ответ дан Doug Knesek 18 August 2018 в 06:53
поделиться

Я использую LISTAGG, но возвращаю эту строку для персидской строки!

мой запрос:

SELECT
 listagg(DESCRIPTION,' , ') within group (order by DESCRIPTION) 
FROM
B_CEREMONY

результат:

'A7'1 , ,4F

Пожалуйста, помогите мне .

wow это решение работает:

SELECT listagg(convert(DESCRIPTION, 'UTF8', 'AL16UTF16'),' , ') within group 
(order by DESCRIPTION) 
FROM  B_CEREMONY;
0
ответ дан Ghasem Aladaghlou 18 August 2018 в 06:53
поделиться

11g и выше: используйте listagg :

SELECT 
    col1,
    LISTAGG(col2, ', ') WITHIN GROUP (ORDER BY col2) "names"
FROM table_x
GROUP BY col1

10g и ниже: один из методов заключается в использовании функции:

CREATE OR REPLACE FUNCTION get_comma_separated_value (input_val  in  number)
  RETURN VARCHAR2
IS
  return_text  VARCHAR2(10000) := NULL;
BEGIN
  FOR x IN (SELECT col2 FROM table_name WHERE col1 = input_val) LOOP
    return_text := return_text || ',' || x.col2 ;
  END LOOP;
  RETURN LTRIM(return_text, ',');
END;
/

To используйте функцию:

select col1, get_comma_separated_value(col1) from table_name

Примечание. В некоторых более старых версиях Oracle есть (неподдерживаемая) функция WM_CONCAT, которая может вам помочь - см. здесь для деталей .

В MySQL:

SELECT col1, GROUP_CONCAT(col2) FROM table_name GROUP BY col1
0
ответ дан hsuk 18 August 2018 в 06:53
поделиться

Для тех, кто должен решить эту проблему с помощью Oracle 9i (или ранее), вам, вероятно, придется использовать SYS_CONNECT_BY_PATH, так как LISTAGG недоступен.

Чтобы ответить на OP, следующий запрос отобразит PID из таблицы A и объединить все столбцы DESC из таблицы B:

SELECT pid, SUBSTR (MAX (SYS_CONNECT_BY_PATH (description, ', ')), 3) all_descriptions
FROM (
       SELECT ROW_NUMBER () OVER (PARTITION BY pid ORDER BY pid, seq) rnum, pid, description
       FROM (
              SELECT a.pid, seq, description
              FROM table_a a, table_b b
              WHERE a.pid = b.pid(+)
             )
      )
START WITH rnum = 1
CONNECT BY PRIOR rnum = rnum - 1 AND PRIOR pid = pid
GROUP BY pid
ORDER BY pid;

Также могут быть экземпляры, в которых ключи и значения содержатся в одной таблице. Следующий запрос может использоваться там, где нет таблицы A, и существует только таблица B:

SELECT pid, SUBSTR (MAX (SYS_CONNECT_BY_PATH (description, ', ')), 3) all_descriptions
FROM (
       SELECT ROW_NUMBER () OVER (PARTITION BY pid ORDER BY pid, seq) rnum, pid, description
       FROM (
              SELECT pid, seq, description
              FROM table_b
             )
      )
START WITH rnum = 1
CONNECT BY PRIOR rnum = rnum - 1 AND PRIOR pid = pid
GROUP BY pid
ORDER BY pid;

Все значения могут быть переупорядочены по желанию. Отдельные конкатенированные описания могут быть переупорядочены в предложении PARTITION BY, и список PID может быть переупорядочен в конечном предложении ORDER BY.


Альтернативно: могут быть моменты, когда вы хотите объединить все значения из целой таблицы в одну строку.

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

В следующем запросе константа string ' 1 ', но любое значение будет работать:

SELECT SUBSTR (MAX (SYS_CONNECT_BY_PATH (description, ', ')), 3) all_descriptions
FROM (
       SELECT ROW_NUMBER () OVER (PARTITION BY unique_id ORDER BY pid, seq) rnum, description
       FROM (
              SELECT '1' unique_id, b.pid, b.seq, b.description
              FROM table_b b
             )
      )
START WITH rnum = 1
CONNECT BY PRIOR rnum = rnum - 1;

Индивидуальные конкатенированные описания могут быть переупорядочены в предложении PARTITION BY.

Несколько других ответов на этой странице также упомянули об этом чрезвычайно полезная ссылка: https://oracle-base.com/articles/misc/string-aggregation-techniques

2
ответ дан JonathanDavidArndt 18 August 2018 в 06:53
поделиться

Как видно из большинства ответов, LISTAGG является очевидным вариантом. Однако один раздражающий аспект с LISTAGG заключается в том, что если общая длина конкатенированной строки превышает 4000 символов (предел для VARCHAR2 в SQL), то возникает ошибка ниже, которую трудно управлять в версиях Oracle до 12.1

ORA-01489: результат конкатенации строки слишком длинный

Новая функция, добавленная в 12cR2, является предложением ON OVERFLOW в LISTAGG. Запрос, включающий это предложение, будет выглядеть так:

SELECT pid, LISTAGG(Desc, ' ' on overflow truncate) WITHIN GROUP (ORDER BY seq) AS desc
FROM B GROUP BY pid;

Вышеуказанное ограничивает вывод до 4000 символов, но не будет вызывать ошибку ORA-01489.

Это некоторые из дополнительные опции ON OVERFLOW:

  • ON OVERFLOW TRUNCATE 'Contd..': в конце строки отобразится 'Contd..' (по умолчанию ...)
  • ON OVERFLOW TRUNCATE '' : Это будет отображать 4000 символов без какой-либо завершающей строки.
  • ON OVERFLOW TRUNCATE WITH COUNT: отобразится общее количество символов в конце после завершающих символов. Например: - ...(5512) '
  • ON OVERFLOW ERROR: Если вы ожидаете, что LISTAGG потерпит неудачу с ошибкой ORA-01489 (которая по умолчанию по умолчанию).
4
ответ дан Kaushik Nayak 18 August 2018 в 06:53
поделиться

Попробуйте этот код:

 SELECT XMLAGG(XMLELEMENT(E,fieldname||',')).EXTRACT('//text()') "FieldNames"
    FROM FIELD_MASTER
    WHERE FIELD_ID > 10 AND FIELD_AREA != 'NEBRASKA';
-1
ответ дан Mamta D 18 August 2018 в 06:53
поделиться
  1. LISTAGG обеспечивает лучшую производительность, если сортировка является обязательной (00: 00: 05.85) SELECT pid, LISTAGG(Desc, ' ') WITHIN GROUP (ORDER BY seq) AS description FROM B GROUP BY pid;
  2. COLLECT обеспечивает наилучшую производительность, если сортировка не требуется (00: 00: 02.90) : SELECT pid, TO_STRING(CAST(COLLECT(Desc) AS varchar2_ntt)) AS Vals FROM B GROUP BY pid;
  3. COLLECT с упорядочением бит медленнее (00: 00: 07.08): SELECT pid, TO_STRING(CAST(COLLECT(Desc ORDER BY Desc) AS varchar2_ntt)) AS Vals FROM B GROUP BY pid;

Все остальные методы были медленнее.

0
ответ дан Misho 18 August 2018 в 06:53
поделиться
  • 1
    Было бы полезно уточнить ваш ответ. – Jon Surrell 12 February 2015 в 18:28
  • 2
    Джон, я не хотел повторять из статьи, но вкратце это результаты: 1. LISTAGG обеспечивает лучшую производительность, если сортировка является обязательной (00: 00: 05.85) 2. COLLECT обеспечивает лучшую производительность, если сортировка не является необходимо (00: 00: 02.90): SELECT pid, TO_STRING (CAST (COLLECT (Desc) AS varchar2_ntt)) AS Vals FROM B GROUP BY pid; 3. COLLECT с упорядочением бит медленнее (00: 00: 07.08): SELECT pid, TO_STRING (CAST (COLLECT (Desc ORDER BY Desc) AS varchar2_ntt)) AS Vals FROM B GROUP BY pid; Все остальные методы были медленнее. – Misho 19 May 2015 в 08:06
  • 3
    Вы можете просто отредактировать свой ответ, чтобы включить соответствующую информацию. – Jon Surrell 19 May 2015 в 08:07
  • 4
    Я был слишком поздно в редактировании, и именно поэтому я добавил его снова. Извините, что я новичок здесь и только начинаю навязывать это. – Misho 19 May 2015 в 08:10

Или функция Oracle STRAGG (column).

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

-3
ответ дан PerformanceDBA 18 August 2018 в 06:53
поделиться

Прежде чем запускать запрос выбора, запустите это:

SET SERVEROUT ON SIZE 6000

SELECT XMLAGG(XMLELEMENT(E,SUPLR_SUPLR_ID||',')).EXTRACT('//text()') "SUPPLIER" 
FROM SUPPLIERS;
1
ответ дан tomrozb 18 August 2018 в 06:53
поделиться

Существует также функция XMLAGG, которая работает с версиями до 11.2. Поскольку WM_CONCAT является недокументированным и не поддерживается Oracle , рекомендуется не использовать его в производственной системе.

С помощью XMLAGG вы можете сделать следующее:

SELECT XMLAGG(XMLELEMENT(E,ename||',')).EXTRACT('//text()') "Result" 
FROM employee_names

Что это значит,

  • помещает значения столбца ename (объединенные запятой) из таблицы employee_names в элемент xml (с тегом E)
  • извлекает текст этого
  • агрегата xml (конкатенировать его)
  • вызывает итоговый столбец «Результат»
15
ответ дан zb226 18 August 2018 в 06:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: