У меня есть сценарий в DB2, где у меня есть значение столбца как
Выберите значение из таблицы, где id='02346'
Ценить
1,2,3,4,5,6,7
Я хочу преобразовать это значение выше, как показано ниже, используя запрос DB2.
1 2 3 4 5 6 7
Как я могу этого добиться? я
Используя оракул, это делается, как показано ниже. с тестом как (выберите столбец «421907802490;421907672085;421911460415;421905464170;421907802292» из двойного) выберите результат regexp_substr(col, '[^;]+', 1, level) из теста соединить по уровню <= length(regexp_replace(col, '[^;]+')) + 1;
Запустите его как есть.
select x.tok
from
-- uncomment this and comment out "(values ...) t (id, value)"
-- table t
(
values ('02346', '1,2,3,4,5,6,7')
) t (id, value)
, xmltable
(
'for $id in tokenize($s, ",") return <i>{string($id)}</i>'
passing
t.value as "s"
columns
tok varchar(4000) path '.'
) x
where t.id = '02346'
Обновление Если вы не находитесь в Db2 for LUW, вы можете использовать тот же подход RCTE:
with
-- Uncomment to run as is
/*
mytab (id, value) as
(
select '02346', '1,2,3,4,5,6,7' from sysibm.sysdummy1
),
*/
cte (tok, value) as
(
select
substr (value, 1, coalesce (nullif (locate (',', value) - 1, -1), length (value)))
, substr (value, nullif (locate (',', value) + 1, 1))
from mytab
where id = '02346' and length (value) <> 0
union all
select
substr (value, 1, coalesce (nullif (locate (',', value) - 1, -1), length (value)))
, substr (value, nullif (locate (',', value) + 1, 1))
from cte
where value is not null
)
select tok
from cte
Результат тот же:
Рабочий пример
Какая у вас версия db2 и платформа?
Db2 v12 / мэйнфрейм z/os
Обновленный запрос также не работал. Использование версии для мэйнфреймов db2 v12 / z/os. Я использую dbeaver в качестве клиента. Ошибка SQL [42601]: НЕПРАВИЛЬНЫЙ СИМВОЛ "MYTAB". НЕКОТОРЫЕ СИМВОЛЫ, КОТОРЫЕ МОГУТ БЫТЬ ЗАКОННЫМИ: DSN_INLINE_OPT_HINT. SQLCODE=-104, SQLSTATE=42601, ДРАЙВЕР=4.29.24
Всегда указывайте свою платформу и версию Db2. zDb2 не поддерживает values .... Обновленный ответ должен работать на zDb2. Если вы не раскомментируете закомментированный блок, вы должны указать свою реальную таблицу вместо mytab, конечно.
Если вы работаете в LUW, используете относительно новую версию и можете включить режим совместимости с Oracle, ваш запрос будет работать сразу после установки. Пробовал с:
[db2inst1@db2server ~]$ db2set
DB2_COMPATIBILITY_VECTOR=ORA
[db2inst1@db2server ~]$ db2 "with test as (select '421907802490;421907672085;421911460415;421905464170;421907802292' col from dual) select regexp_substr(col, '[^;]+', 1, level) result from test connect by level <= length(regexp_replace(col, '[^;]+')) + 1"
RESULT
----------------------------------------------------------------
421907802490
421907672085
421911460415
421905464170
421907802292
5 record(s) selected.
Протестировано с:
sudo docker pull ibmcom/db2
sudo docker run ...
sudo docker exec -it db2server bash
su - db2inst1
Это не работает в DB2 SQL. Ошибка SQL [42601]: НЕПРАВИЛЬНЫЙ СИМВОЛ "(". НЕКОТОРЫЕ СИМВОЛЫ, КОТОРЫЕ МОГУТ БЫТЬ ДОПУСТИМЫМИ: