0

在 DB2 中,我有一个结果字符串,例如

Color|Product|Category|Price|...

现在我喜欢生成四个(或 n)列,其中包含由管道拆分的每个字符串标记

Col1      Col2     Col3     Col4     Col...
Color     Product  Category Price    ...

我正在寻找具有任意数量的列的通用解决方案。

此结果的用途是在 UNION 中与另一个 SELECT-Query 一起使用。

有任何想法吗?

4

1 回答 1

1

你想在哪里展示这个输出?通过 DB2CLP 或者另一个程序。

如果要在另一个程序中检索值,则取决于程序如何管理输出,并且您只需在扫描输出时放入制表即可。

例如,对于 Java

System.out.println(col1+"\t"+col2+"\t"+col3);

另一方面,如果您想在 DB2CLP 或类似的 shell 中检索值,并使用这些管道从数据库中检索您的字符串,那么您应该创建一个标量函数来处理该字段,然后再将其返回给用户。

您将需要以下功能

最好的方法是创建一个递归函数,对每个令牌进行迭代。基本情况是字符串为空或字符串未通过管道结束。递归情况是字符串有管道时。

该过程是读取字符(到变量中)直到第一个管道。如果检测到管道,则添加模拟制表符的空格数量,然后使用尾随字符串调用相同的函数。

您应该传递要读取的字符串以及已处理的字符串。

功能可能是这样的

函数.sql

CREATE OR REPLACE MODULE TEST@
ALTER MODULE TEST PUBLISH
  FUNCTION PROCESS (
  STRING varchar(255),
  NEW_STRING varchar(255)
) RETURNS varchar(255)
@

ALTER MODULE TEST ADD
  FUNCTION PROCESS (
  STRING varchar(255),
  NEW_STRING varchar(255)
) RETURNS varchar(255)
PROC: begin
  DECLARE IND INT;
  DECLARE LEN INT;
  DECLARE MODU INT;
  DECLARE CHARS INT;
  DECLARE TAB INT DEFAULT 8;
  DECLARE PRE VARCHAR(255);
  DECLARE POS VARCHAR(255);

  SET IND = POSSTR(STRING, '|');
  IF (IND <> 0) THEN
    SET PRE = SUBSTR(STRING, 1, IND - 1);
    SET POS = SUBSTR(STRING, IND + 1);

    SET NEW_STRING = TEST.PROCESS (POS, NEW_STRING);

    SET PRE = TRIM(PRE);
    SET LEN = LENGTH(PRE);
    SET MODU = MOD(LEN, TAB);
    IF (MODU <> 0) THEN
      SET CHARS = TAB - MODU;
      WHILE (CHARS <> TAB) DO
        SET PRE = CONCAT (PRE, ' ');
        SET CHARS = CHARS + 1;
      END WHILE;
    END IF;
  ELSE
    SET PRE = STRING;
  END IF;

  RETURN CONCAT (PRE, COALESCE(NEW_STRING,''));

end PROC@

编译和执行

db2 -td@ -f function.sql ; db2 "values test.process('Color|Product|Category|Price|...','')"

1
-----------------------------------------
Color     Product       CategoryPrice     ...
  1 record(s) selected.
于 2013-07-25T14:33:33.480 回答