在DB2中,我有一个结果字符串,例如像
Color|Product|Category|Price|...
现在我想生成四个(或n个)列,其中包含由管道分割的每个字符串标记
Col1 Col2 Col3 Col4 Col...
Color Product Category Price ...
我正在寻找一个任意数量的cols的通用解决方案。
使用此结果是在UNION中使用另一个SELECT-Query。
有什么想法吗?
答案 0 :(得分:1)
您想在哪里展示此输出?通过DB2CLP ou另一个程序。
如果要在另一个程序中检索值,它取决于程序如何管理输出,并且只是在扫描输出时放置列表。
例如,对于Java
System.out.println(col1+"\t"+col2+"\t"+col3);
另一方面,如果要检索DB2CLP或类似shell中的值,使用这些管道从数据库中检索字符串,您应该创建一个标量函数来处理该字段,然后再将其返回给用户
你需要像
这样的功能最好的方法是创建一个递归函数,迭代每个令牌。基本情况是字符串为空或字符串未通过管道完成。递归的情况是字符串有管道。
过程是读取字符(变量)直到第一个管道。如果检测到管道,则添加模拟选项卡的空间数量,然后使用尾随字符串调用相同的函数。
您应该传递要读取的字符串以及已处理的字符串。
功能可以是这样的
<强> function.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.