SQLSTATE 58004, Ошибка «неверное назначение qn c» при использовании NULL в JSON_OBJECT () с LISTAGG в DB2 LUW - PullRequest
2 голосов
/ 18 апреля 2020

Представляется интересная комбинация функций, которая приводит к ошибке в Db2 LUW v11.5.0.0. Чтобы воспроизвести, напишите:

CREATE TABLE t (a INT);
INSERT INTO t VALUES (1), (2);

SELECT '[' || listagg(
  json_object(
    KEY 'a' VALUE a,
    KEY 'b' VALUE b
  ), ','
) WITHIN GROUP (ORDER BY a) || ']'
FROM (
  SELECT a, NULL b
  FROM t
  ORDER BY a
);

Я использую LISTAGG, чтобы обойти отсутствующую поддержку Db2 LUW JSON_ARRAYAGG.

Я получаю следующую ошибку:

Оператор или команда SQL не выполнены из-за системной ошибки базы данных. (Причина «неверное присвоение qn c».). SQLCODE = -901, SQLSTATE = 58004, DRIVER = 4.7.85

Вполне вероятно, что ошибка в синтаксическом анализаторе. Кажется, что-то явно не так. Как это можно предотвратить / обойти?

1 Ответ

2 голосов
/ 18 апреля 2020

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

Приведите литерал NULL к указанному c типу * 1004. *

SELECT '[' || listagg(
  json_object(
    KEY 'a' VALUE a,
    KEY 'b' VALUE b
  ), ','
) WITHIN GROUP (ORDER BY a) || ']'
FROM (
  SELECT a, CAST(NULL AS VARCHAR(1)) b -- Workaround here
  FROM t
  ORDER BY a
);

Приведите значение в JSON_OBJECT

Возможно, не удастся узнать тип b, который также может быть нумерацией c, вместо строки.

SELECT '[' || listagg(
  json_object(
    KEY 'a' VALUE a,
    KEY 'b' VALUE CAST(b AS VARCHAR(32672)) -- Workaround here
  ), ','
) WITHIN GROUP (ORDER BY a) || ']'
FROM (
  SELECT a, NULL b
  FROM t
  ORDER BY a
);

Удалите предложение ORDER BY, которое в данном случае не требуется (это может быть, если было предложение FETCH FIRST)

SELECT '[' || listagg(
  json_object(
    KEY 'a' VALUE a,
    KEY 'b' VALUE b
  ), ','
) WITHIN GROUP (ORDER BY a) || ']'
FROM (
  SELECT a, NULL b
  FROM t
  -- Workaround here
);

Добавление выражения, которое "запутывает" значение NULL

SELECT '[' || listagg(
  json_object(
    KEY 'a' VALUE a,
    KEY 'b' VALUE COALESCE(b, NULLIF(1, 1)) -- Workaround here
  ), ','
) WITHIN GROUP (ORDER BY a) || ']'
FROM (
  SELECT a, NULL b
  FROM t
  ORDER BY a
);

Все это приводит к желаемому

1                                  |
-----------------------------------|
[{"a":1,"b":null},{"a":2,"b":null}]|
...