首页 > 解决方案 > SQLSTATE 58004,在 DB2 LUW 中将 JSON_OBJECT() 中的 NULL 与 LISTAGG 一起使用时出现错误“无效的 qnc 分配”

问题描述

似乎有一个有趣的功能组合会导致 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 语句或命令失败。(原因“无效的 qnc 分配”。)。SQLCODE=-901,SQLSTATE=58004,驱动程序=4.7.85

很可能是解析器中的一个错误。似乎没有什么明显的错误。如何防止/解决这种情况?

标签: sqljsondb2db2-luw

解决方案


我发现了一些我想在这里记录的解决方法,以防有人也遇到这种情况:

将 NULL 文字转换为特定类型

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,也可能是数字,而不是字符串。

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}]|

推荐阅读